如何理解LockService并正确实现?

use*_*287 13 locking google-apps-script

守则摘要

我有一个特定的领域中使用了大约80个用户谷歌的Apps脚本项目,但该应用程序是由我执行(即Publish> Deploy as web app> Execute the app as: Me).

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

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

我想这可能是由于并发使用脚本(因为两个通知电子邮件具有相同的时间戳)并且最近了解到了Lock Service.

我正在使用此帖子以确保我正确理解Lock并如何实现它,以防止由于并发脚本使用而导致条目未出现在Google表格中.

履行

我的场景的伪代码是:

Code.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; 
Run Code Online (Sandbox Code Playgroud)

问题

01) 是的实现LockService,getScriptLock(),waitLock()releaseLock()正确的吗?

02) 是否建议使用SpreadsheetApp.flush(),如果是,上述实施是否正确?

术语(供参考)

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

锁定:
互斥锁的表示.

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

Lock类有4种方法:

hasLock()
Boolean,如果获取了锁,则返回true.

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

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

waitLock(timeoutInMillis)
void,尝试获取锁定,在提供的毫秒数后超时超时.

LockService类有3个方法:

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

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

getUserLock()
Lock,获取一个锁,阻止当前用户同时运行一段代码.

Jac*_*own 10

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

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;
Run Code Online (Sandbox Code Playgroud)

希望有所帮助!