2012-12-14 36 views
1

我正在使用LockService来避免重复的操作,但是我无法让tryLock在我的测试过程中失败。无法使LockService tryLock失败

假设这段代码应该在几乎同时运行多个时间的情况下在ScriptProperties中写入一个错误,但目前还没有。

第二个应用程序实例在尝试锁定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; 
} 

回答

1

有趣的问题。在对此进行了一点处理之后,我认为锁定工作正常,但看起来并不是因为Google Apps脚本似乎不允许并发获取请求,而是将它们排队。通过将你的锁定测试移动到服务器端,它就可以工作。

如果您的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; 
} 

希望这已经回答了您关于锁定的问题。尽管它在我的脑海里提出了关于获取请求排队的问题。它只是来自同一用户的请求吗?我很乐意听到其他人提供的信息,尽管这可能属于某个问题。

+0

太棒了:你的回答,你的推理,甚至你最后的问题//非常感谢锁定服务的保证,Fausto –