#javascript #google-apps-script
Вопрос:
Я надеюсь на вашу помощь, так как проблема для меня нестандартная и я не смог ее решить после многих попыток.
Проблема
У меня есть стандартная функция для приема почтовых запросов, и она стабильно работает на небольших объемах, пример кода:
let sheet = SpreadSheet.getSheetByName("name")
let dateTime = Utilities.formatDate(new Date(), "GMT 3", "dd.MM.yyy HH:mm:ss") // Moscow time
<...>
function doPost(e) {
sheet.insertRowBefore(2) // adds a line before the second one
sheet.getRange(2, 1).setValue(e.parameter.par1)
sheet.getRange(2, 2).setValue(dateTime)
sheet.getRange(2, 3).setValue(e.parameter.par2)
sheet.getRange(2, 4).setValue(e.parameter.par3)
sheet.getRange(2, 5).setValue(e.parameter.par4)
}
В таблице это выглядит так: Пример
По сути, функция должна выполняться синхронно и работать стабильно, но когда функция получает много запросов (около 140 за 1-10 секунд), она может создать две строки сразу и дважды записать данные в одну и ту же вторую строку. В результате для 140 запросов в таблице имеется ~4 пустых строки, данные из которых были утеряны
Вот как выглядит пустая строка, добавленная по ошибке: Пример
Попытка решить
Чтобы предотвратить одновременное выполнение двух сценариев, я использовал функцию LockService из сценария Google apps, мой код стал выглядеть так:
let sheet = SpreadSheet.getSheetByName("name")
let dateTime = Utilities.formatDate(new Date(), "GMT 3", "dd.MM.yyy HH:mm:ss") // Moscow time
var lock = LockService.getScriptLock() // LockService
<...>
function doPost(e) {
if (lock.tryLock(30000)) { // waiting for a queue 30 seconds
sheet.insertRowBefore(2) // adds a line before the second one
sheet.getRange(2, 1).setValue(e.parameter.par1)
sheet.getRange(2, 2).setValue(dateTime)
sheet.getRange(2, 3).setValue(e.parameter.par2)
sheet.getRange(2, 4).setValue(e.parameter.par3)
sheet.getRange(2, 5).setValue(e.parameter.par4)
lock.releaseLock() // unblocking
}
}
Я пробовал разные времена ожидания в очереди, но это не привело к успеху. Функция продолжала оставлять пустые строки
Я прошу вашей помощи, так как я долго ломал голову над этой проблемой. Что делать? Я буду благодарен за любую информацию
Ответ №1:
Пожалуйста, попробуйте выполнить flush() до setValue
Комментарии:
1. Спасибо!! Это помогло, единственное , что я поставил
flush()
не только доsetValue
, но и после
Ответ №2:
В дополнение к flush()
этому я бы рекомендовал заменить это:
// 5 calls (get/set) to server
sheet.getRange(2, 1).setValue(e.parameter.par1)
sheet.getRange(2, 2).setValue(dateTime)
sheet.getRange(2, 3).setValue(e.parameter.par2)
sheet.getRange(2, 4).setValue(e.parameter.par3)
sheet.getRange(2, 5).setValue(e.parameter.par4)
с этим:
// 1 call (get/set) to the server
sheet.getRange(2,1,2,5).setValues([
e.parameter.par1,
dateTime,
e.parameter.par2,
e.parameter.par3,
e.parameter.par4
])
Лучшие практики: Пакетные операции
Комментарии:
1. Спасибо за ваше редактирование, оно действительно улучшило структуру кода, а также помогло в решении проблемы