Фоновые задачи позволяют отдать работу платформе и сразу вернуться: поставьте вызов в очередь по HTTP, мгновенно получите jobId, а очередь выполнит функцию с ретраями, бэкоффом и dead-letter-очередью — без Redis, парка воркеров и самописного цикла опроса.
Задачи выполняют те же функции, что вы деплоите для HTTP-трафика, — с теми же секретами, слоями и наблюдаемостью. Отличается только триггер: durable-строка в очереди вместо живого запроса.
Жизненный цикл задачи#
Каждая задача проходит небольшой и явный конечный автомат. Воркер забирает PENDING-задачи пачками, выполняет их в статусе RUNNING и записывает SUCCEEDED — либо планирует ретрай при сбое. Когда попытки исчерпаны, задача попадает в DEAD — dead-letter-состояние, где можно изучить ошибку и вручную вернуть задачу в очередь.
Постановка в очередь и опрос#
Постановка — один HTTP-вызов; ответ — 202 Accepted с идентификатором задачи. Дальше опрашивайте эндпоинт задачи (или подпишитесь на события запусков в консоли), чтобы получить результат:
# Enqueue: returns immediately with a job id (the function runs in the background) curl -X POST "https://api.inquir.org/functions/{functionId}/invoke-async" \ -H "Authorization: Bearer $INQUIR_API_KEY" \ -H "Content-Type: application/json" \ -d '{"event": {"orderId": "ord_123"}}' # -> { "jobId": "…", "status": "PENDING" } # Poll until the job reaches a terminal state curl "https://api.inquir.org/jobs/{jobId}" \ -H "Authorization: Bearer $INQUIR_API_KEY" # -> { "status": "SUCCEEDED", "resultJson": … } (or FAILED / DEAD with lastError)
Ретраи и бэкофф#
Ретраи включаются на каждую постановку: передайте maxAttempts (до 100), и неудачные попытки вернутся в очередь с экспоненциальным бэкоффом — 1 с, 2 с, 4 с и далее, с потолком 5 минут и джиттером против эффекта толпы.
maxAttemptsсчитает попытки целиком, а не только ретраи, и запуск, потерянный вместе с воркером, тоже считается; по умолчанию — 1 (без ретраев).- Пока задача выполняется, воркер продлевает её аренду, поэтому длинная задача работает до таймаута своей функции, а не обрывается по visibility-таймауту (22,5 мин). Рипер вмешивается, только когда аренду перестают продлевать — воркер упал или стал недоступен. Если попытки остались, он возвращает задачу в очередь, если нет — отправляет в dead-letter, поэтому задача, которая раз за разом роняет воркер, останавливается после
maxAttemptsзапусков. Пишите обработчики так, чтобы повторная доставка была безопасной. - Поддерживается отложенный старт — до 7 дней; удобно для напоминаний и окон охлаждения.
Идемпотентность и контроль конкурентности#
Две опции при постановке избавляют систему от дублей и лавин:
idempotencyKey— повторная постановка с тем же ключом вернёт исходную задачу вместо дубликата (в ответе будет флагdeduplicated).concurrencyKey+concurrencyLimit— ограничьте, сколько задач с одним ключом выполняются одновременно (на клиента, на репозиторий — на что угодно).priority— при глубокой очереди задачи с большим приоритетом забираются первыми.
Dead-letter-очередь#
Когда падает последняя попытка или её воркер перестаёт продлевать аренду, задача становится DEAD с финальной ошибкой, а в историю записывается терминальная FAILED-инвокация. Для потерянной аренды ошибка — reaped: visibility timeout; the worker stopped renewing the lease and no attempts remain. Мёртвые задачи видны в консоли: устраните причину, нажмите requeue — и задача вернётся в PENDING со свежим запасом попыток.
Задачи, durable-инстансы или пайплайны#
Берите задачу, когда одна функция должна один раз отработать в фоне — с ретраями и dead-letter-очередью. Берите durable-инстанс, когда этот единичный запуск нужно адресовать по устойчивому id — идемпотентный старт и статус для опроса (см. «Durable Functions»). Берите графовый пайплайн, когда несколько функций образуют воркфлоу с ветвлением, fan-out, запуском по расписанию (cron) или шагом подтверждения человеком. Внизу у всех трёх — одна и та же очередь на Postgres.