我使用LockService来避免重复操作,但是在测试期间我无法使tryLock失败。
据说这个代码在几乎同时运行多次时会在ScriptProperties中写错误,但到目前为止还没有。
第二个App实例应该在tryLock 1秒后失败,而第一个实例正在睡眠15秒,对吗?
有什么建议吗?
function doGet() {
testingLockService(1000, 15000);
return;
}
function testingLockService(trying, sleeping) {
var lock = LockService.getPrivateLock();
var hasMutex = lock.tryLock(trying);
if (hasMutex == false) { ScriptProperties.setProperty("LockService",new Date().toString()+" tryLock failed"); return; }
Utilities.sleep(sleeping);
lock.releaseLock();
return;
}
答案 0 :(得分:1)
有趣的问题。稍微玩了一下之后,我认为锁定工作正常,它似乎不是因为Google Apps脚本似乎不允许并发获取请求,而是将它们排队。通过将锁定测试移动到服务器端,它可以正常工作。
如果你的get请求向用户返回一些东西而不是把它放在一个脚本属性中,这就更容易调试。
以下代码将演示排队的get请求。要测试:发出两个并发请求,并查看返回的时间戳,有趣的是,您会注意到第二个请求在第一个请求的结束时间戳之前没有开始时间戳,无论您将它们组合得多么接近。所以第二个请求可以完全有效地获得锁定。这是代码:
function doGet() {
var app = UiApp.createApplication();
var tS = new Date();
var gotLock = testingLockService(0, 5000);
var tF = new Date();
var label = app.createLabel(gotLock ? 'Got the lock, and slept' : "Didn't get the lock");
app.add(label);
var label = app.createLabel('tS ' + tS.getTime());
app.add(label);
var label = app.createLabel('tF ' + tF.getTime());
app.add(label);
var label = app.createLabel('t delta ' + (tF - tS));
app.add(label);
return app;
}
function testingLockService(trying, sleeping) {
var lock = LockService.getPrivateLock();
var hasMutex = lock.tryLock(trying);
if (!hasMutex) { return false; }
Utilities.sleep(sleeping);
lock.releaseLock();
return true;
}
现在,为了证明锁定确实有效,只需将锁定代码移动到服务器端即可。再次,要测试,打开两个浏览器窗口,然后单击两个按钮。这次你会看到第二个请求无法获得锁定并立即返回。
function doGet() {
var app = UiApp.createApplication();
var serverHandler = app.createServerHandler('doClick');
var button = app.createButton().setText("click me").addClickHandler(serverHandler);
app.add(button);
return app;
}
function doClick() {
var app = UiApp.getActiveApplication();
// code from here on is identical to previous example
var tS = new Date();
var gotLock = testingLockService(0, 5000);
var tF = new Date();
var label = app.createLabel(gotLock ? 'Got the lock, and slept' : "Didn't get the lock");
app.add(label);
var label = app.createLabel('tS ' + tS.getTime());
app.add(label);
var label = app.createLabel('tF ' + tF.getTime());
app.add(label);
var label = app.createLabel('t delta ' + (tF - tS));
app.add(label);
return app;
}
function testingLockService(trying, sleeping) {
var lock = LockService.getPrivateLock();
var hasMutex = lock.tryLock(trying);
if (!hasMutex) { return false; }
Utilities.sleep(sleeping);
lock.releaseLock();
return true;
}
希望这已经回答了你关于锁定的问题。虽然它在我的脑海中提出了关于获取请求排队的问题。它只是来自同一个用户的请求吗?如果他们有更多关于这方面的信息,我很乐意听到别人的意见,不过,也许这本身就属于一个问题。