Движок durable-оркестрации координирует длительные stateful-воркфлоу — цепочки шагов, fan-out и ожидание событий или подтверждений. Каждый запуск чекпойнтится в Postgres, поэтому прогоны переживают рестарты — без отдельной очереди или хранилища состояния, которые пришлось бы обслуживать. Про durable-ретраи для развёрнутых функций-контейнеров смотрите также фоновые задачи.
Оркестратор (async-генератор) пошагово вызывает функции-активности. Каждый шаг чекпойнтится в Postgres, поэтому прогресс надёжен: после рестарта оркестратор переигрывает записанную историю и продолжает ровно с того места, где остановился.
Как работает оркестрация
Пишите оркестратор как async-генератор и делайте yield на каждом шаге. Активности выполняют реальную работу (могут быть недетерминированы); оркестратор только координирует и обязан быть детерминированным — используйте ctx.callActivity() для результатов и ctx.currentUtcDateTime для времени, а не Date.now() или Math.random().
ctx.callActivityWithRetry() повторяет нестабильный шаг с экспоненциальной задержкой, а ctx.continueAsNew() перезапускает длинный цикл с чистым состоянием, чтобы история оставалась ограниченной.
// orchestrator.js — coordinate activities, a durable timer, and an approval gate. // Register it like any function, then start it via global.durable or the HTTP API. exports.orchestrator = async function* (ctx) { const order = ctx.getInput(); // Each activity result is checkpointed to Postgres (replayed, not re-run, on resume). const charged = yield ctx.callActivity('chargeCard', order); // Retry a flaky step with exponential backoff. yield ctx.callActivityWithRetry('reserveStock', { maxNumberOfAttempts: 3, firstRetryIntervalInMilliseconds: 1000, backoffCoefficient: 2, }, order); // Durable timer — the orchestration suspends (no container, no compute) for 24h. yield ctx.createTimer(new Date(Date.now() + 24 * 60 * 60 * 1000)); // Wait for a human approval or webhook — resumes when the event is raised. const approval = yield ctx.waitForExternalEvent('Approval', 86400000); if (approval && approval.approved) { return yield ctx.callActivity('ship', order); } return yield ctx.callActivity('refund', charged); };
Durable-таймеры и внешние события
ctx.createTimer() ждёт минуты, часы или дни, а ctx.waitForExternalEvent() приостанавливает оркестрацию до прихода именованного события (подтверждение человека, колбэк вебхука). Во время ожидания оркестрация приостановлена: она не держит контейнер и не расходует вычислительные ресурсы — и возобновляется автоматически, когда срабатывает таймер или приходит событие.
Запуск и управление оркестрациями
Из функции внедрённый клиент global.durable управляет инстансами: startNew(name, id?, input?), getStatus(id), waitForCompletion(id, ms), raiseEvent(id, name, data) и terminate(id, reason). Необязательный ключ идемпотентности у startNew устраняет дубли запусков.
HTTP API
Оркестрациями можно управлять и по HTTP: POST /durable/orchestrations/{name}/start возвращает 202 с идентификатором инстанса и URI для статуса, отправки события и завершения; прогресс опрашивайте через GET /durable/orchestrations/{id}/status.