Правильно ли я использую службу блокировки сценариев Google Apps?

#google-apps-script #web-applications

#google-apps-script #веб-приложения

Вопрос:

У меня есть 3 функции скрипта приложений в скрипте. Скрипт развернут как веб-приложение общего доступа.

Каждая функция считывает данные из собственной таблицы Google. Каждая функция ничего не записывает в листы.

Я применил скрипт приложений ‘LockService’ к каждой функции, чтобы предотвратить одновременный доступ нескольких пользователей к электронным таблицам через веб-приложение. По сути, заставляя каждого пользователя ждать, пока скрипт предыдущего пользователя не закончит чтение. Они получают возможность прочитать 3 листа.

Я обнаружил, что иногда это может привести к некоторой задержке в 4-5 секунд для пользователей перед обновлением приложения, что довольно неприятно.

Тогда мой вопрос заключается в следующем: а) стоит ли мне беспокоиться о службе блокировки, поскольку я просто читаю данные электронной таблицы, и, возможно, основная цель службы блокировки — предотвратить конфликты между одновременным чтением И записью

Или

б) правильно ли я это реализовал, поскольку одновременное чтение данных также может вызвать конфликты при получении таких вещей, как значения диапазона и т.д.

Спасибо

РЕДАКТИРОВАТЬ: если опция ‘a’, то мне интересно, какова цель LockService? Возможно, это одна из причин (как у меня в другом месте в других скриптах), когда вы используете несколько ‘google.script.run.’ Один за другим для доступа к одной и той же электронной таблице с помощью разных функций, тогда — поскольку они выполняются асинхронно — могут возникнуть конфликты, если оба запроса пытаются получить данные.

просто размышляю на самом деле….

Ответ №1:

Вам не нужно использовать LockService , если все, что вы делаете, это считываете данные. Следовательно, вариант (a).

Нет необходимости защищать Apps Script или Google Sheets от параллелизма, даже при операциях записи от одного пользователя. Каждый параллельный доступ, который вы выполняете из Apps Script, выполняется полностью независимо друг от друга, это новый экземпляр вашего приложения, который ничем не делится с другими, он даже может быть запущен на совершенно другом сервере. И Google Sheets отлично справляются с параллелизмом, параллельная совместная работа — это весь смысл приложений G Suite.

Итак, когда вам нужно LockService ?

Когда этого требует логика вашего приложения. Например, чтобы защитить себя от искажения собственных данных. Допустим, вы хотите подсчитать, сколько у вас было кликов, и сохранить это число на листе, например Sheet1!B2 . Таким образом, ваш код будет выглядеть следующим образом:

 function countClicks() {
  var r = SpreadsheetApp.getActive().getSheetByName('Sheet1').getRange('B2');
  var clicks = r.getValue();
  clicks = clicks   1;
  r.setValue(clicks);
}
  

Если эта функция выполняется одновременно, вы не повредите свою память или не нарушите работу Google Sheets, все, что произойдет, это то, что вы можете перезаписать себя, как если бы у вас было несколько пользователей, пытающихся ввести текст в одной ячейке: выигрывает последний.

Но ваша логика была бы нарушена, то есть несколько одновременных кликов могут быть засчитаны как один. Именно тогда появляется LockService для защиты вашей логики:

 function countClicks() {
  var r = SpreadsheetApp.getActive().getSheetByName('Sheet1').getRange('B2');
  var lock = LockService.getDocumentLock();
  lock.waitLock(10000); //throws exception if fails to acquire lock
  //you could try-catch it, but that's irrelevant in this example
  r.setValue(r.getValue() 1);
  SpreadsheetApp.flush(); //forces the script to actually send the values to Sheets
  lock.releaseLock();
}
  

Надеюсь, это проясняет ситуацию.

Кстати, это просто очень неудачный пример. Вы не должны так считать клики, потому что, как вы указали, блокировка приводит к значительной задержке в вашей системе. Поэтому вам следует поискать альтернативы, возможно, разделить ваши данные на пользователей или использовать атомарные операции, такие как appendRow.

Комментарии:

1. Спасибо. Следует добавить, что веб-приложение развернуто от имени «Меня», но доступно «Любому, включая анонимного». Так влияет ли это на мои проблемы с одновременным доступом и, следовательно, на потребность в LockService — в том смысле, что это одна и та же учетная запись пользователя со многими разными пользователями.

2. массовый выигрыш со ссылкой на appendRow … именно то, о чем я пытаюсь узнать в случае, когда мне приходится использовать Sheets как базу данных

3. обычно да, но это зависит от варианта использования. В приведенном выше неубедительном countClicks примере это делается именно так, r.getValue() происходит после получения блокировки.