Опубликовано:
Vercel Workflow SDK 5.3.1 запускает воркфлоу идемпотентно одним шагом
Vercel выпустила Workflow SDK 5.3.1: start() запускает воркфлоу и закрепляет hook одним атомарным шагом, а повторный запуск с тем же токеном отклоняется.
Vercel выпустила Workflow SDK 5.3.1. Функция start() теперь принимает запуск и закрепляет hook по токену за один атомарный шаг, поэтому повторный старт с тем же токеном не создаёт второе выполнение.
Раньше для этого использовали связку getHookByToken() и затем start(). Между проверкой токена и запуском оставался промежуток, в котором два одинаковых запроса могли создать два выполнения; в документации это названо гонкой дублирующихся стартов. Атомарный старт убирает промежуток: токен принадлежит ровно одному запуску.
Если дубликат всё же приходит, start() выбрасывает HookConflictError, и в ошибке есть conflictingRunId — идентификатор запуска-владельца. Полезные данные дубликата можно передать владельцу через resumeHook. Hook существует с момента приёма запуска, поэтому resumeHook срабатывает ещё до начала выполнения, а ранние сообщения буферизуются и доставляются по порядку.
Внутри воркфлоу createHook({ token }) с тем же токеном привязывается к уже закреплённому хуку. Новый хук не регистрируется, отдельный шаг не добавляется, а getConflict() возвращает null.
const run = await start(processOrder, [orderId, note], {
experimental_hook: { token: `order:${orderId}` },
});
Токен работает как ключ идемпотентности и берётся из предметной области: номер заказа, счёта, импорта или запроса. Если воркфлоу вообще не открывает hook, токен остаётся только ключом идемпотентности, а запуск завершается обычным образом.
Опция experimental_minRetention держит токен недоступным после завершения запуска, отсчёт идёт от start(), так что поздние дубликаты тоже получают отказ. Обновление доступно в workflow 5.3.1, подробности Vercel приводит в документации по идемпотентности. Отдельных условий доступа или цены для этой возможности в сообщении нет.