Google apps script 如何理解LockService并正确实施它?
代码摘要 我有一个Google Apps脚本项目,在一个特定的域中有大约80个用户使用,但是该应用程序是由我执行的(即Google apps script 如何理解LockService并正确实施它?,google-apps-script,locking,Google Apps Script,Locking,代码摘要 我有一个Google Apps脚本项目,在一个特定的域中有大约80个用户使用,但是该应用程序是由我执行的(即PublishDeploy as web app将应用程序执行为:me) 该脚本的功能之一是从自定义表单(使用HTML服务)填充谷歌表单,然后通知我自己和提交用户(通过使用简单的登录系统和cookie识别) 它已经工作了大约6个月,但是有1-2次通知邮件已经发送,但是谷歌表单条目没有出现 我认为这可能是由于同时使用了脚本(因为两封通知电子邮件具有相同的时间戳),并且最近了解到 我
Publish
Deploy as web app
将应用程序执行为:me
)
该脚本的功能之一是从自定义表单(使用HTML服务
)填充谷歌表单,然后通知我自己和提交用户(通过使用简单的登录系统和cookie识别)
它已经工作了大约6个月,但是有1-2次通知邮件已经发送,但是谷歌表单条目没有出现
我认为这可能是由于同时使用了脚本(因为两封通知电子邮件具有相同的时间戳),并且最近了解到
我使用这篇文章是为了确保我对Lock
有正确的理解,以及如何实现它,以防止由于并发脚本使用而在Google工作表中不出现条目
实施
我的场景的伪代码是:
代码.gs
问题
function myFunction() {
var lock = LockService.getScriptLock();
lock.tryLock(5000);
if (!lock.hasLock()) {
Logger.log('Could not obtain lock after 5 seconds.');
return;
}
else if (lock.hasLock()) {
Logger.log('got the lock');
//Browser.inputBox("TESTING123");
Utilities.sleep(10000);
}
lock.releaseLock();
}
01)锁服务LockService
、getScriptLock()
、waitLock()
和releaseLock()的实现是否正确
02)是否建议使用SpreadsheetApp.flush()
,如果是,上述实现是否正确
术语(供参考)
发件人:
:
互斥锁的表示
:
防止对代码段的并发访问
Lock类有4种方法:
布尔值,如果已获取锁,则返回true
void,释放锁,允许等待锁的其他进程继续
布尔值,尝试获取锁,在提供的毫秒数后超时
void,尝试获取锁,在提供的毫秒数之后超时,出现异常
LockService类有3种方法:
Lock,获取阻止当前文档的任何用户同时运行代码段的锁
Lock,获取阻止任何用户同时运行代码段的锁
Lock,获取阻止当前用户同时运行代码段的锁。在上面的伪代码中,一旦脚本没有获得锁,它仍将继续运行代码。这就是我们想要的行为吗?向用户抛出服务器繁忙消息是更好的做法或选项。
像这样:
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;
var active_电子表格=电子表格app.openById(“bbb”);
//开始-开始锁定在这里
var lock=LockService.getScriptLock();
试一试{
lock.waitLock(30000);//等待30秒,等待其他人使用代码段并锁定停止,然后继续
}捕获(e){
Logger.log('30秒后无法获得锁');
返回HtmlService.createHtmlOutput(“服务器忙,请稍后再试”)
//如果这是一个异步调用的服务器端代码,则返回一个错误代码并在客户端显示相应的消息
return“错误:服务器正忙,请稍后再试…抱歉:(”
}
//注意:如果在上面的catch块中运行return,则以下操作将不会运行,因为函数将退出
var active_sheet=active_电子表格.getSheetByName(“条目”);
var new_start_row=活动的_sheet.getLastRow()+1;
//做很多事情-例如根据以前的条目应用动态背景颜色颜色,定义目标范围和设置值,设置数据验证
SpreadsheetApp.flush();//应用所有挂起的电子表格更改
锁。释放锁();
//这里是端锁
返回;
希望有帮助!所以我想我发现了锁定系统的一个问题。也就是说,当你触发一个弹出框(显示在工作表中)时在脚本中,它会删除锁…或者类似的东西,因为它肯定不会保留锁。我有一段代码,我正在尝试运行,基本上没有弹出框,锁定系统可以工作。没有问题,当第一个用户拥有锁时,haslock确实会返回false…但随后您引入了一个弹出框和锁定系统不能像它应该的那样工作,即使弹出框和那一行代码,或者它后面的任何一行代码没有被执行,也会给第二个用户一个锁。我在弹出框之后延迟了一下尝试,因为我最初认为它可能没有等待输入回来,所以它只是有点跳过在弹出框被推到工作表上之后…但是即使在代码的弹出框部分之后有很长的延迟(脚本仍然在我面前运行)第二个用户仍然被授予一个锁。也许我做得不对,但是弹出框是唯一会抛出我的代码的东西。我尝试了try、catch和if、if-else…但没有运气,我甚至尝试了if、else…我知道这不是因为trylock/waitlock太长或太短。我尝试了一系列值,我也知道它不是sleep bc我在代码中尝试了一系列的值,以及不同的位置。在不同的google用户帐户上进行了大量测试,在公元前几天的不同日子里,我原本以为这是我在装傻什么的。但实际上,似乎弹出框是唯一将其发送出预订的东西。。
锁定系统何时工作的示例
function myFunction() {
var lock = LockService.getScriptLock();
lock.tryLock(5000);
if (!lock.hasLock()) {
Logger.log('Could not obtain lock after 5 seconds.');
return;
}
else if (lock.hasLock()) {
Logger.log('got the lock');
//Browser.inputBox("TESTING123");
Utilities.sleep(10000);
}
lock.releaseLock();
}
二,
使用建议的try,catch语句
function myFunction() {
var lock = LockService.getScriptLock();
try {
lock.waitLock(5000); // wait 5 seconds try to get lock
} catch (e) {
Logger.log('Could not obtain lock after 5 seconds.');
}
Utilities.sleep(10000);
//Browser.inputBox("TESTING123");
lock.releaseLock();
}
function myFunction() {
var lock = LockService.getScriptLock();
try {
lock.waitLock(5000); // wait 5 seconds try to get lock
} catch (e) {
Logger.log('Could not obtain lock after 5 seconds.');
}
Utilities.sleep(10000);
Browser.inputBox("TESTING123");
lock.releaseLock();
}
它确实捕获了错误,并显示弹出窗口,表示无法获取错误
不起作用的示例
function myFunction() {
var lock = LockService.getScriptLock();
lock.tryLock(5000);
if (!lock.hasLock()) {
Logger.log('Could not obtain lock after 5 seconds.');
return;
}
else if (lock.hasLock()) {
Logger.log('got the lock');
Browser.inputBox("TESTING123");
Utilities.sleep(10000);
}
lock.releaseLock();
}
二,
使用建议的try-catch语句
function myFunction() {
var lock = LockService.getScriptLock();
try {
lock.waitLock(5000); // wait 5 seconds try to get lock
} catch (e) {
Logger.log('Could not obtain lock after 5 seconds.');
}
Utilities.sleep(10000);
//Browser.inputBox("TESTING123");
lock.releaseLock();
}
function myFunction() {
var lock = LockService.getScriptLock();
try {
lock.waitLock(5000); // wait 5 seconds try to get lock
} catch (e) {
Logger.log('Could not obtain lock after 5 seconds.');
}
Utilities.sleep(10000);
Browser.inputBox("TESTING123");
lock.releaseLock();
}
弹出框在所有情况下都会出现。它不应该出现,因为弹出框没有显示