1

アクションの重複を避けるために LockService を使用していますが、テスト中に tryLock を失敗させることはできません。

おそらく、このコードは、ほぼ同時に複数回実行すると ScriptProperties にエラーを書き込むはずですが、今のところそうではありません。

最初のインスタンスが 15 秒間スリープしている間に、1 秒間の tryLock の後、2 番目の App インスタンスは失敗するはずですよね?

助言がありますか?

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;
}
4

1 に答える 1

1

興味深い質問です。これを少し試してみたところ、ロックは機能していると思いますが、Google Apps Scriptが同時取得リクエストを許可していないようで、キューに入れているためではないようです。ロックテストをサーバー側に移動すると、機能します。

これは、getリクエストでスクリプトプロパティに配置するのではなく、ユーザーに何かを返すようにすると、デバッグがはるかに簡単になります。

次のコードは、キューに入れられているgetリクエストを示しています。テストするには、2つの同時リクエストを作成し、戻ってくるタイムスタンプを確認します。興味深いことに、2番目のリクエストには、最初のリクエストの終了タイムスタンプの前に開始タイムスタンプがありません。したがって、2番目の要求は完全に有効にロックを取得できます。コードは次のとおりです。

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;
}

ここで、ロックが機能することを証明するには、ロックコードをサーバー側に移動するだけです。繰り返しますが、テストするには、2つのブラウザウィンドウを開いて、両方のボタンをクリックします。今回は、2番目のリクエストがロックの取得に失敗し、すぐに戻ることがわかります。

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;
}

うまくいけば、それはロックに関するあなたの質問に答えました。getリクエストのキューイングについて頭に浮かぶ質問がありますが。同じユーザーからのリクエストだけですか?他の誰かがそれについてもっと情報を持っているなら、私は誰かから聞いてみたいですが、それ自体が質問に属しているのかもしれません。

于 2012-12-17T12:21:13.423 に答える