如何理解LockService并正确实现? [英] How to understand LockService and implement it correctly?

查看:54
本文介绍了如何理解LockService并正确实现?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

代码摘要

我有一个 Google Apps Script 项目,该项目由特定域内的大约 80 个用户使用,但是该应用程序由我执行(即 Publish > Deploy as web app > 执行应用程序为:Me).

I have a Google Apps Script project that is used by around 80 users within a specific domain, however the app is executed by me (ie Publish > Deploy as web app > Execute the app as: Me).

该脚本的功能之一是从自定义表单(使用 HTML 服务)填充 Google 表格,然后通知我自己和提交用户(通过使用简单的登录系统和cookies).

One of the functions of the script is to populate a Google Sheet from a custom form (using HTML Service) and then notify myself and the submitting user (who is identified through the use of a simple login system and cookies).

它已经正常工作了大约 6 个月,但是有 1-2 次通知电子邮件已发送,但 Google Sheet 条目没有出现.

It has been working fine for about 6 months, however on 1-2 occasions the notification email has been sent but the Google Sheet entry has not appeared.

我认为这可能是由于同时使用脚本(因为两封通知电子邮件具有相同的时间戳)并且最近了解到 锁服务.

I am thinking this might be due to concurrent use of the script (as two notification emails had the same timestamp) and have recently learned of Lock Service.

我使用这篇文章是为了确保我对 Lock 以及如何实现它有正确的理解,以防止由于并发脚本使用而导致条目未出现在 Google 表格中.

I am using this post to ensure I have the correct understanding of Lock and how to implement it in order to prevent entries not appearing in the Google Sheet due to concurrent script usage.

实施

我的场景的伪代码是:

代码.gs

var active_spreadsheet = SpreadsheetApp.openById("bbb");

// BEGIN - start lock here

var lock = LockService.getScriptLock();
try {
   lock.waitLock(30000); // wait 30 seconds for others' use of the code section and lock to stop and then proceed
 } catch (e) {
   Logger.log('Could not obtain lock after 30 seconds.');
 }

var active_sheet = active_spreadsheet.getSheetByName("ENTRIES");
var new_start_row = active_sheet.getLastRow() + 1;

//  Do lots of stuff - ie apply dynamic background colors based on previous entries colors, define the target range and set values, set data validations  

SpreadsheetApp.flush(); // applies all pending spreadsheet changes
lock.releaseLock();

// END - end lock here

return; 

问题

01)LockServicegetScriptLock()waitLock()的实现releaseLock() 正确吗?

02) 是否推荐使用SpreadsheetApp.flush(),如果是,上面的实现是否正确?

02) Is it recommended to use SpreadsheetApp.flush(), and if so is the implementation above correct?

术语(供参考)

来自:https://developers.google.com/apps-script/reference/锁

锁定:
互斥锁的表示.

Lock:
A representation of a mutual-exclusion lock.

LockService:
防止对代码段的并发访问.

LockService:
Prevents concurrent access to sections of code.

Lock 类有 4 个方法:

The Lock class has 4 methods:

hasLock()
布尔值,如果获得锁则返回真.

hasLock()
Boolean, Returns true if the lock was acquired.

releaseLock()
void,释放锁,允许其他等待锁的进程继续.

releaseLock()
void, Releases the lock, allowing other processes waiting on the lock to continue.

tryLock(timeoutInMillis)
布尔值,尝试获取锁,在提供的毫秒数后超时.

tryLock(timeoutInMillis)
Boolean, Attempts to acquire the lock, timing out after the provided number of milliseconds.

waitLock(timeoutInMillis)
void,尝试获取锁,在提供的毫秒数后超时并出现异常.

waitLock(timeoutInMillis)
void, Attempts to acquire the lock, timing out with an exception after the provided number of milliseconds.

LockService 类有 3 个方法:

The LockService class has 3 methods:

getDocumentLock()
Lock,获取一个锁,防止当前文档的任何用户同时运行一段代码.

getDocumentLock()
Lock, Gets a lock that prevents any user of the current document from concurrently running a section of code.

getScriptLock()
Lock,获取一个锁,防止任何用户同时运行一段代码.

getScriptLock()
Lock, Gets a lock that prevents any user from concurrently running a section of code.

getUserLock()
Lock,获取阻止当前用户并发运行一段代码的锁.

getUserLock()
Lock, Gets a lock that prevents the current user from concurrently running a section of code.

推荐答案

在上面的伪代码中,一旦脚本没有获得锁,它仍然会继续运行代码.这是预期的行为吗?向用户发送服务器繁忙消息是更好的做法或选项.像这样:

In the above pseudo code, once the script doesn't get a lock it will still proceed to run the code. Is that the intended behavior? It is a better practice or option to throw a server busy message to the user. Like so:

var active_spreadsheet = SpreadsheetApp.openById("bbb");

// BEGIN - start lock here

var lock = LockService.getScriptLock();
try {
    lock.waitLock(30000); // wait 30 seconds for others' use of the code section and lock to stop and then proceed
} catch (e) {
    Logger.log('Could not obtain lock after 30 seconds.');
    return HtmlService.createHtmlOutput("<b> Server Busy please try after some time <p>")
    // In case this a server side code called asynchronously you return a error code and display the appropriate message on the client side
    return "Error: Server busy try again later... Sorry :("
}

// note:  if return is run in the catch block above the following will not run as the function will be exited

var active_sheet = active_spreadsheet.getSheetByName("ENTRIES");
var new_start_row = active_sheet.getLastRow() + 1;

//  Do lots of stuff - ie apply dynamic background colors based on previous entries colors, define the target range and set values, set data validations  

SpreadsheetApp.flush(); // applies all pending spreadsheet changes
lock.releaseLock();

// END - end lock here

return;

希望有帮助!

这篇关于如何理解LockService并正确实现?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆