Я использую электронную таблицу Google для хранения контактной информации, которую я собираю с веб-сайта (соответствует GDPR, не беспокойтесь), и я синхронизирую этот лист с Mailchimp, используя собственный скрипт приложения, который работает в фоновом режиме.
Более подробно, я использую временный лист в качестве буфера, который заполняется данными, которые пользователи отправляют через формы сайта (я использую контактную форму 7 Google Sheets Connector). Мой скрипт запускается каждый раз, когда событие «INSERT_ROW» запускается в «буферном» листе. Он анализирует данные, сохраняет их на последнем листе и, в конце концов, освобождает «буфер».
Теперь, зная о потенциальных проблемах параллелизма, я написал код в следующей форме:
function onChange(e) {
// Script initializaztion
if (!formNames.includes(formName) || e.changeType != "INSERT_ROW") return;
let lock = LockService.getScriptLock();
try {
lock.waitLock(60000);
// Get new stuff from Form sheet
.
.
.
// Get existing data and compare with new
compareData();
// New entries
insertNewDataIntoFinalSheet();
// Updates
updatesExistingDataInFinalSheet();
// Clean up the buffer sheet
deleteRowsFromSiteForms();
console.log(formName);
} catch(e) {
console.log(e);
}
lock.releaseLock();
}
Но я не уверен, что Локк делает то, что ожидал. А в Google Docs не очень ясно, как его использовать.
Если я не правильно понимаю Google Docs, любой Lock
не позволяет одновременно выполнять разделы кода. Этот сервис позволяет сценариям предотвращать одновременный доступ к разделам кода. Это может быть полезно, когда несколько пользователей или процессов изменяют общий ресурс и хотят предотвратить коллизии (Google docs).
Теперь представьте себе следующий сценарий: Пользователь A в своем браузере заполняет форму. В то же самое время (ну, почти) Пользователь B делает то же самое в другом браузере где-то еще в мире. Соединитель CF7 браузера пользователя А отправляет данные на мой «буферный» лист и получает блокировку, чтобы мой скрипт начал свою работу. Через наносекунду пользовательская форма B вставляет другие данные в «буфер», вызывая, таким образом, выполнение сценария. Этот новый экземпляр сценария пытается получить блокировку, но блокируется блокировкой пользователя A.
В то же время экземпляр сценария пользователя A завершает свою работу и очищает все, удаляя также данные, введенные с помощью Пользователь B ! Когда экземпляр сценария пользователя A снимает блокировку, сценарий пользователя B включается, но обнаруживает, что его данные сметены экземпляром сценария пользователя A.
В идеале мне нужен способ «заморозить» любую модификацию «буферный» лист (включая вставку новых строк) до тех пор, пока каждый экземпляр скрипта не завершит свою работу.
Но, насколько я понимаю, а также, судя по некоторым странным ошибкам в моих журналах, это не то, что getScriptlock () выполняет (и getUserlock () или getDocumentlock () нет).
Может кто-нибудь помочь мне понять, как мне использовать Google LockService для этого?
Заранее спасибо
РЕДАКТИРОВАТЬ
Те, кто прокомментировал мой пост (в частности, @TheMaster), уловили самую суть проблемы, поэтому позвольте мне добавить дополнительную информацию / мысли. Это ошибка, которую я получаю (иногда) в моем журнале Stackdriver
Очевидно, мой скрипт пытается получить доступ к данным, когда он не должен. Я подозреваю, что это сценарий, который я изобразил: второй экземпляр скрипта находит «буфер», очищенный первым.
Как говорит @TheMaster, проблема в том, что нет способа действительно «заблокировать» «документ, если доступ к документу осуществляется через какой-либо внешний ресурс, например, Zapier, или, как в моем случае, коннектор Wordpress или какой-либо запрос API (разработчики Google, не должны ли вы решить эту проблему?).