Как я могу облегчить одновременное использование пользователей в веб-приложении скриптов Google Apps? - PullRequest
3 голосов
/ 16 января 2020

В настоящее время я создаю веб-приложение, которое читает и пишет в Google Sheet. По сути, это приложение для форм, которое принимает входные данные из формы 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]);
    }
  }
}

Сводная страница приложения (страница 5, появляется после всех шагов записи), затем считывает эти данные (используя .getRange().getValues()) и затем отображает их на странице .

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

  1. Использование LockService для принудительного использования приложения только одним человеком за раз (не идеально, поскольку приложение будет использоваться для цитирования клиентов и доноров). не хочу заставлять пользователей ждать).
  2. Многопоточность
  3. Стеки

Я не уверен, как 2 или 3 будут работать, или даже возможно в GAS , Может ли кто-нибудь пролить свет на то, можно ли облегчить работу нескольких пользователей и как?

Заранее спасибо

Ответы [ 2 ]

2 голосов
/ 16 января 2020

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

В вашей точке входа [вероятно, doGet (), возможно doPost ()], сгенерируйте UUID с var session_id = Utilities.getUuid();

Затем передайте этот идентификатор сеанса в свой шаблон и включите его во все будущие запросы обратно в скрипт приложения.

Запишите UUID в столбец на листе в вашей функции addProjectInputs(), затем измените вашу функцию addFurtherInputs(), чтобы найти правильную строку на основе UUID (вместо того, чтобы всегда брать последнюю), и запишите свои обновления в эту строку.

Этот подход гарантирует, что многие пользователи могут работать, не беспокоясь о перезаписи друг друга, и без задержек из-за блокировок.

См. https://developers.google.com/apps-script/reference/utilities/utilities#getUuid ()

0 голосов
/ 16 января 2020

Я испробовал все эти решения.

  1. LockService хорошо работает даже для больших листов и большего количества пользователей. Вам необходимо отслеживать частоту действий ваших пользователей. Если вы не используете смоделированное поведение веб-сокета, вы обычно ничего не боитесь.
  2. Многопоточность здесь не применима.
  3. Стеки. Если я вас правильно понимаю, стеки организованы на основе листов и формул. Обычно я делю свои приложения Sheets по уровню доступа и типу действий. Насчет доступа все понятно. Типы действий: pu sh, рассчитывает, тянет. Каждый лист имеет только одно действие. Я использую appendRow одинарные записи для pu sh. А также я использую классы для расчета того, что будет в пу sh. Это позволяет мне сохранить один звонок и не брать pull.getDataRange().getValues() каждый раз после того, как я пишу, чтобы вытащить. Я использую формулы, так что тяга всегда актуальна. Вы должны быть знакомы с понятиями «кусочек прошлого», «остатки за период», чтобы понять это.

Это может быть немного туманно, потому что я плохо говорю по-английски sh , Мои извинения.

...