【问题标题】:Google App Script: LockService doesn't work谷歌应用脚​​本:LockService 不起作用
【发布时间】:2020-05-25 19:02:01
【问题描述】:

我正在尝试使用 GAS(谷歌应用脚​​本)实现聊天机器人。并且在 LockService 方面遇到了一些麻烦。它似乎无法正常工作或根本无法正常工作。

当我从适当的聊天中收到新消息时,我保存了延迟值(8 秒)以忽略来自此聊天的后续消息。我使用 lockService 来避免跳过并发消息。

但是它不起作用,并且遗漏了一些消息。

我的代码:

function get_message_safely(chat_id, message) {
  var lock = LockService.getScriptLock();
  const delay = 8*1000; // 8 seconds
  // save time of getting message
  var get_time = (new Date()).getTime();

  // lock
  // set lock before accessing data

    try {
      if (lock.hasLock()) { // ==always false (for unknown reasons)
        sendLog('get_message_safely/hasLock', 'lock = true' + '\n' + message);
      }
      lock.waitLock(10000); // wait 10 seconds for others' use of the code section and lock to stop and then proceed
    } catch (error) {
      sendLog('get_message_safely/lock_service',  'ОШИБКА: ' + error);
      send_message(chat_id,  "Наши сервера сейчас загружены. Отправьте сообщение повторно или попробуйте позже.");
      lock.releaseLock();
      return;
    }



  // get data from PropertiesService
  var scriptProperties = PropertiesService.getScriptProperties();
  var chat_access_flag = scriptProperties.getProperty(chat_id);

  if (chat_access_flag != undefined) { // if chat already exist
    if (chat_access_flag == 'false') {  // access denied
      sendLog('get_message_safely/lock_service',  'LockService: доступ запрещен.\n' + message);
      lock.releaseLock();
      return;
    } 
    var lock_time = Number(chat_access_flag);
    if (get_time <= lock_time) { // access denied: lock_time is still actual
      sendLog('get_message_safely/lock_service',  'LockService: доступ запрещен т.к. время не прошло:\n' + lock_time + ' - ' + get_time + ' = ' + (lock_time - get_time) +  '\n' + message);
      lock.releaseLock();
      return;
    }
    sendLog('get_message_safely/lock_service',  'LockService: доступ разрешен:\n' + lock_time + ' - ' + get_time + ' = ' + (lock_time - get_time) + '\nnew_lock_time: ' + (get_time + delay) + '\n' + message);
  }

  scriptProperties.setProperty(chat_id, get_time + delay);     // if access is allowed, set new delay

  // lock release
  lock.releaseLock(); // release the lock

  get_message(chat_id, message); // handling message
}

所以,有时我遇到这种情况(当我同时发送很多消息时),lockService 应该处理它但它没有:

案例(示例):

// lock_time == a;
// get 1 message: access allowed. So set new value to lock_time (=b)
// lock_time == b; 
// get 2 message: access denied. get_time < lock_time (=b)
// lock_time still == b;
// get 3 message: access allowed: get_time > lock_time, where lock_time == a (!???). So set new value to lock_time (=c);
// lock_time == с (??)
// get 4 message: access denied: get_time < lock_time (=b)

由于 lockService 处理消息应该按顺序完成。但是某些消息由于某种原因访问 PropertiesService 并同时获得相同的日期。

这让我大吃一惊。你知道这里发生了什么吗? 我怎样才能达到理想的结果?

【问题讨论】:

  • 嗨@NikitaGoncharov!在研究了您的代码后,我发现.hasLock() 总是返回false。在您的情况下,这可能意味着之前既没有调用过 .waitLock() 也没有调用过 .tryLock()。您能否实现这些方法中的任何一个,看看是否有帮助?

标签: google-apps-script


【解决方案1】:

研究您的代码后,我发现.hasLock() 总是返回false。如果我弄错了,请原谅我。在您的情况下,这可能意味着之前既没有调用过 .waitLock() 也没有调用过 .tryLock()。要解决此问题,您必须使用上述方法之一。您可以在链接上阅读一些示例用法。如果您需要进一步的帮助,请随时问我。

【讨论】:

  • 嗨!谢谢您的回答。我的示例(案例)中描述了主要问题。我仅将 .hasLock() 用于 debagging。我想如果我的脚本的另一个实例获得了锁,那么当前实例中的 .hasLock() 应该是真的(这意味着我的锁不起作用)。但是,如果误解了 lock.hasLock() - 我认为这没什么大不了的。我的debag案仍然是真实的,我不明白为什么。这是我的主要问题。
  • 为什么 lockService 在我的情况下不起作用,并且没有将我的脚本的所有同时实例放入此代码块中的队列中。我在我的 ServiceProperties 中设置了一个新值,但是如果在同一时刻执行 2 个或多个脚本,它们都会得到旧值,当只有第一个应该得到旧值而其他应该得到更新值时
  • 当您说“我在我的 ServiceProperties 中设置了一个新值,但如果同时执行 2 个或更多脚本,它们都会获得旧值”我理解您指的是行`var scriptProperties = PropertiesService.getScriptProperties(); var chat_access_flag = scriptProperties.getProperty(chat_id);` 如果是这样,您是为chat_id 使用不同的值还是使用相同的值?
  • 我对来自同一个聊天的消息使用相同的 chat_id。我的案例正是关于来自同一聊天的消息。所以是的 - 相同的 chat_id
  • 如果我理解正确,您想从不同的用户调用方法.getScriptProperties() 并获得不同的值作为回报。如果我对您的情况的假设是正确的,那么该操作是不可能的。 Here 声明.getScriptProperties() 在同一脚本的所有用户之间共享。如果您希望来自不同用户的不同结果,您可以尝试使用.getUserProperties()。另外,您能否在更新后尝试记录变量以确认它是否真的改变了?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-08-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多