timeoutSeconds (максимум 900 секунд). Любая задача, которая не может завершиться за это время — полная повторная синхронизация, разветвление по каждой записи, сторонний API, который ограничивает вас по скорости, — должна быть разделена на более мелкие запуски.
enqueueJob делает именно это: он просит воркеров Twenty позже запустить одну из логических функций вашего приложения в отдельном процессе с собственным лимитом времени. Вызов возвращается немедленно.
Поставить запуск в очередь
ИмпортируйтеenqueueJob из twenty-sdk/logic-function и укажите universalIdentifier логической функции, которую вы хотите запустить.
src/logic-functions/sync-all-contacts.ts
payload как аргумент обработчика, точно так же, как любой другой триггер. Она должна принадлежать тому же приложению, что и вызывающая сторона — постановка в очередь функции другого приложения будет отклонена с ошибкой Logic function not found.
enqueueJob возвращает управление, как только задание принято, а не когда оно выполнено. Он не возвращает результат целевой функции — если вам нужно потом его прочитать, пусть целевая функция запишет результат в key-value store или в запись рабочего пространства.Параметры задания
Приоритет пока нельзя настраивать. Задания в очереди всегда выполняются с самым низким приоритетом, поэтому работа платформы никогда не откладывается из‑за заданий приложений. Возможность управлять приоритетом появится скоро.
Использование: постраничный проход по длинной синхронизации
Классический шаблон — функция, которая ставит саму себя в очередь со следующим курсором. Каждый запуск обрабатывает одну страницу работы, уверенно укладываясь в собственный таймаут, а цепочка останавливается, когда больше нечего делать.src/logic-functions/sync-contacts-page.ts
Разветвление по каждой записи
Когда работа естественным образом выполняется по отдельным элементам, поставьте по одному заданию на элемент и позвольте воркерам обрабатывать их параллельно, вместо того чтобы перебирать элементы в цикле внутри одной функции.Рекомендации для длительной работы
Два правила покрывают почти любое долгое задание: рекурсивный вызов вместо цикла и обработка ограниченного блока за один запуск. Запуск, который пытается сделать всё сразу, — это сценарий отказа: он упирается в таймаут и при повторной попытке начинает всё сначала с нуля. Вместо этого выберите размер блока так, чтобы он с запасом завершался в пределахtimeoutSeconds, сохраните свою позицию и поставьте в очередь следующий запуск.
src/logic-functions/enrich-companies-batch.ts
- Размер блока выбирайте, исходя из самого медленного элемента, а не среднего.
CHUNK_SIZE × время обработки в худшем случаедолжно помещаться вtimeoutSecondsс запасом, иначе хвост блока будет потерян, когда запуск обрежет таймаут. - Сделайте условие завершения явным. Вызывайте рекурсивно только пока вернулся полный блок. Цепочка, которая останавливается только на основе «нет результатов», будет продолжаться бесконечно, если источник когда‑либо вернёт укороченную страницу посередине.
- Сохраняйте прогресс перед постановкой в очередь следующего запуска, чтобы при сбое звена цепочки она возобновлялась с последнего завершённого блока, а не с начала.
- Сделайте каждый блок идемпотентным. Повторная обработка одного блока после повторной попытки не должна приводить к двойной записи — привязывайте операции записи к идентификатору обрабатываемой записи или к внешнему идентификатору.
- Отдавайте предпочтение цепочке из блоков перед одним гигантским разветвлением, когда работа обращается к внешнему сервису с ограничением по скорости: цепочка с
delayMsсаморегулирует темп, тогда как тысячи заданий, поставленных в очередь одновременно, сразу становятся допустимыми к выполнению.