Как предотвратить одновременный запуск сценария с помощью LockService? - PullRequest
0 голосов
/ 10 декабря 2018

Если у меня есть электронная таблица с 15 отдельными проектами, каждый с одной функцией onEdit ().У меня проблема в том, что иногда скрипт не запускается.Я думаю, что проблема в параллелизме.

Сценарии разные, но обычно выглядят так:

function onEdit(e){ 
  var edited_range = e.range;

  var edited_row = edited_range.getRow();

  var activeSheet = e.source.getActiveSheet(); 
  var ss = SpreadsheetApp.getActiveSpreadsheet(); 

  var source_sheet = ss.getSheetByName("N.Arb Pitches"); 
  var target_sheet = ss.getSheetByName("N.Arb In Progress");
  var last_row = target_sheet.getLastRow(); 

  var range_values = target_sheet.getRange("A1:A").getValues(); 

  var range_length = range_values.filter(String).length + 1;

  var target_range = target_sheet.getRange(range_length,1); 


  if (activeSheet.getName() == "N.Arb Pitches") { 
        if (edited_range.getColumn() == 13) {
          if (edited_range.getValue().toLowerCase() == "yes") {
             target_sheet.insertRowAfter(last_row);  
             source_sheet.getRange(edited_row,1,1,12).copyTo(target_range); 
            source_sheet.deleteRow(edited_row)  }}}; 

}

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

function onEdit(e) {

var lock = LockService.getDocumentLock();

try {
    lock.waitLock(10000); 
}
catch (e) {
Browser.msgBox("error");
}
var start = new Date();
var startTime = Number(start.getTime()).toFixed(0);
  SpreadsheetApp.getActiveSheet().getRange('N1').setValue('lock1');
  SpreadsheetApp.getActiveSheet().getRange('N2').setValue('success1');


  SpreadsheetApp.getActiveSheet().getRange('N3').setValue('RELEASED1');
  SpreadsheetApp.getActiveSheet().getRange('N4').setValue(startTime);
  SpreadsheetApp.flush();
    Utilities.sleep(2000);
  lock.releaseLock();    
  
}
 

второй из которых содержит этот код

function onEdit(e) {

var lock = LockService.getDocumentLock();

  
try {
    lock.waitLock(10000); 
}
catch (e) {
Browser.msgBox("error");
}
  var start = new Date();
var startTime = Number(start.getTime()).toFixed(0);
  SpreadsheetApp.getActiveSheet().getRange('O1').setValue('lock2');
  SpreadsheetApp.getActiveSheet().getRange('O2').setValue('success2');


    SpreadsheetApp.getActiveSheet().getRange('O3').setValue('RELEASED2');
  SpreadsheetApp.getActiveSheet().getRange('O4').setValue(startTime);
  SpreadsheetApp.flush();
  Utilities.sleep(2000);
  lock.releaseLock();  

}
 

Как я уже сказал, я не понимаю LockService (), но я думаю, что это означает, что когда я вычитаю два миллисекунды, напечатанные сценариями, я должен видетьразница не менее 2000, но это НЕ то, что я вижу, что на самом деле ~ 200 в обоих направлениях.

То, что я чувствую, должно происходить, исходя из того, что я понимаю, что любой сценарий onEdit () запускается первым, он заблокирует документ и предотвратит запуск любых других сценариев.Затем второй скрипт будет застрять в цикле try (), пока первый не снимет свою блокировку.Затем, когда первый завершится, он снимет блокировку, и второй сценарий будет свободен для запуска, или наоборот, если второй сценарий будет запущен первым.

Это не имеет никакого смысла, исходя из того, что я вижу на самом делебывает.Что такое правильное понимание этого кода?Как я могу выполнить то, что я описываю, когда на самом деле ни один код не выполняется одновременно между проектами?Я бы задавал более прямые вопросы, но пытался, и мои мысли достаточно перемешаны. Я не знаю, как правильно сформулировать вопрос.

Спасибо.

1 Ответ

0 голосов
/ 11 декабря 2018

Я не уверен, как работает LockService, но если ваша проблема заключается в параллелизме, вы можете попробовать добавить SpreadsheetApp.flush() между двумя функциями.

flush()

Применяет все ожидающие изменения в электронной таблице.

Операции с электронной таблицей иногда объединяются для повышения производительности, например, при выполнении нескольких вызовов Range.getValue ().Однако иногда вы можете захотеть убедиться, что все ожидающие изменения внесены сразу, например, чтобы показать данные пользователей во время выполнения скрипта.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...