如何为 Google Apps 脚本网络应用程序上的并发用户提供便利?

Emi*_*ile 5 concurrency locking google-sheets google-apps-script

我目前正在创建一个可以读取和写入 Google 表格的网络应用程序。它本质上是一个表单应用程序,它从 HTML 表单获取输入,使用appendRow()(以及后续使用getRange()并将setValue()更多数据附加到该行)将其写入工作表。每行代表正在填写的表单的一个实例。请参阅写入过程的示例代码。

/*
Function that is called in Index.html whenever the 'Next' button pressed. This 
gets all inputs from HTML form and stores them in the spreadsheet.

Parameters:
inputArray: a 1x3 array which contains the owner, reference and type of scale.
*/

function addProjectInputs(inputArray) {
  var sheetName = "Inputs";
  var spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
  var sheet = spreadsheet.getSheetByName(sheetName);
  Logger.log(sheet);
  var d = new Date();
  var tz = spreadsheet.getSpreadsheetTimeZone();
  var d = [Utilities.formatDate(d,tz,  "dd/MM/yyyy")];
  var data = d.concat(inputArray);
  Logger.log(data);
  sheet.appendRow(data);
}

/* Function to append further data onto the row created from 
addProjectInputs() */

function addFurtherInputs(idlerArray) {
  var sheetName = "Inputs";
  var spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
  var sheet = spreadsheet.getSheetByName(sheetName);

  var lastRow = sheet.getLastRow();
  var lastColumn = sheet.getLastColumn()-42;

  var arrayEmpty = idlerArray.every(function(i) { return i === ''; });
  Logger.log(arrayEmpty);

  if (arrayEmpty !== true) {
    for (i = 0; i < idlerArray.length; i++) {
      var range3 = sheet.getRange(lastRow,lastColumn+1+i,1,1);
      range3.setValue(idlerArray[i]);
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

应用程序的摘要页面(第 5 页,在所有写入步骤之后出现)然后读取此数据(使用.getRange().getValues()),然后将其显示在页面上。

当一名用户使用该应用程序时效果很好,但该应用程序可能会同时被最多 20 人使用。这是一个问题。例如,如果第二个用户开始使用该应用程序,他们的数据将通过添加新行开始覆盖第一个用户的数据,从而“存档”第一个用户的数据。我遇到了以下潜在的解决方案:

  1. 利用 LockService 强制一次只有一个人使用该应用程序(这并不理想,因为该应用程序将用于引用客户并且不想让用户等待)。
  2. 多线程
  3. 堆栈

我不确定 2 或 3 将如何工作,甚至在 GAS 中是否可能。任何人都可以阐明是否可以为多个用户提供便利,以及如何进行?

提前致谢

Cam*_*rts 3

我会通过为每个用户会话生成一个唯一的 ID 来解决此问题,而不是锁定,您可以将其存储在工作表中并用于稍后匹配值。

在你的入口点 [可能是 doGet(),可能是 doPost()],生成一个 UUIDvar session_id = Utilities.getUuid();

然后将该会话 ID 传递给您的模板,并将其包含在所有将来返回到 Apps 脚本的请求中。

将 UUID 写入函数中工作表的一列addProjectInputs(),然后修改addFurtherInputs()函数以根据 UUID 找到正确的行(而不是始终采用最后一行)并将更新写入该行。

这种方法保证您可以让许多用户工作,而不必担心相互覆盖,并且不会因锁定而造成延迟。

请参阅https://developers.google.com/apps-script/reference/utilities/utilities#getUuid()