如何防止使用LockService运行并发脚本?

时间:2018-12-10 18:20:40

标签: google-apps-script google-sheets

如果我有一个包含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()一样,但是我认为这意味着当我减去脚本打印的两毫秒时间时,我应该看到至少相差2,000,但这不是我所知道的我正在看哪个方向实际上是〜200。

基于我的理解,我认为应该发生的是,无论哪个onEdit()脚本先运行,它都会锁定文档并阻止其他任何脚本运行。然后,第二个脚本将停留在try()循环中,直到第一个脚本释放其锁。然后,当第一个脚本运行完毕时,它将释放锁,第二个脚本将可以自由运行,反之亦然,如果第二个脚本首先运行则相反。

根据我所看到的实际发生,这没有任何意义。对这个代码有什么正确的理解?我如何完成我所描述的内容,其中没有代码实际上在项目之间并发运行?我会问一些更直接的问题,但是尝试了一下,我的想法被弄得一团糟,我不知道如何形成一个适当的问题。

谢谢。

1 个答案:

答案 0 :(得分:0)

我不确定LockService的工作方式,但是如果您的问题是并发性,则可以尝试在两个函数之间添加SpreadsheetApp.flush()

  

flush()

     

应用所有待处理的电子表格更改。

     

电子表格操作有时会捆绑在一起以改善   性能,例如当多次调用Range.getValue()时。   但是,有时您可能需要确保所有待处理的更改   立即制作,例如以脚本形式向用户显示数据   执行。