Фоновые задачи с повторами — без флота воркеров
Фоновые задачи падают: API таймаутят, БД блокируется, сеть моргает. Нужны backoff на шаг, идемпотентные хендлеры и поисковая история сбоев — не while-loop в воркере. Пайплайны Inquir повторяют упавшие шаги, сохраняя чекпоинты завершённой работы.
Обновлено: 2026-06-23
Кратко
Суть ответа
Фоновые задачи с повторами — без флота воркеров. Каждый шаг пайплайна повторяется независимо при сбое. Завершённые шаги остаются чекпоинтами — перезапускается только упавший. Политика retry — конфигурация, не код приложения.
Когда подходит и когда нет
- Async из HTTP, вебхуков или cron, где сбои downstream ожидаемы
- Многошаговые задачи, где повтор всей job дорог или небезопасен
На что обратить внимание
- Повтор всей задачи с нуля перезапускает завершённые шаги — двойные письма, списания, записи без идемпотентности.
- Фиксированный интервал retry бьёт по падающему downstream. Exponential backoff с jitter — boilerplate, который часто копируют неверно.
Ситуация: нагрузка и где обычно ломается
Почему retry фоновых задач сложнее, чем кажется
Часто начинают с fire-and-forget: поставили задачу, надеются на успех. При сбое — grep логов и ручной replay. В масштабе тихие сбои становятся потерей выручки.
Самописные retry-циклы в воркерах теряют состояние при рестарте, дают double-process при recovery и прячут счётчики retry от дашбордов.
Компромиссы
Где ломается DIY retry
Повтор всей задачи с нуля перезапускает завершённые шаги — двойные письма, списания, записи без идемпотентности.
Фиксированный интервал retry бьёт по падающему downstream. Exponential backoff с jitter — boilerplate, который часто копируют неверно.
Как Inquir помогает в этом сценарии
Повторы шагов пайплайна как примитив платформы
Каждый шаг пайплайна повторяется независимо при сбое. Завершённые шаги остаются чекпоинтами — перезапускается только упавший. Политика retry — конфигурация, не код приложения.
История выполнения показывает каждую попытку: вход, выход, длительность, ошибку, число retry. Алерты по failure rate без своего дашборда.
Что вы получаете на платформе
Паттерны retry для фоновых задач
Retry на шаг с backoff
Упавшие шаги — по настраиваемой политике. Завершённые не выполняются заново при падении следующего.
Идемпотентные хендлеры
Upsert по job ID, check-before-write, dedupe-ключи из payload триггера.
Триггер из любой точки входа
HTTP 202, ACK вебхука, cron или другая задача — одна семантика retry.
Поисковая история сбоев
Failed-прогоны по времени, функции или тексту ошибки. Replay из payload без повторного HTTP.
Что сделать дальше, по шагам
Как запускать фоновые задачи с повторами на Inquir
Быстро принять, поставить durable-работу, платформа повторяет упавшие шаги.
Принять и поставить в очередь
HTTP или вебхук возвращает 202. global.durable.startNew() с payload задачи.
Идемпотентные шаги
Каждый шаг проверяет dedupe-key до side effects. Структурированный выход для следующего шага.
Политика retry и алерт
Счётчик retry и backoff в конфиге пайплайна. Алерт при превышении порога failure rate.
Пример кода
Фоновая задача с retriable-шагами пайплайна
HTTP-хендлер ставит работу одной строкой. Шаги пайплайна повторяются независимо при сбое downstream.
export async function handler(event) { const { userId, format } = JSON.parse(event.body || '{}'); if (!userId) return { statusCode: 400, body: JSON.stringify({ error: 'userId required' }) }; const { instanceId: jobId } = await global.durable.startNew('export-data', undefined, { userId, format }); return { statusCode: 202, body: JSON.stringify({ jobId, status: 'queued' }) }; }
export async function handler(event) { const { userId, format } = event.payload ?? {}; const existing = await db.findExport(userId, event.instanceId); if (existing) return { statusCode: 200, body: JSON.stringify({ url: existing.url }) }; const url = await generateAndUploadExport(userId, format); await db.saveExport(userId, event.instanceId, url); return { statusCode: 200, body: JSON.stringify({ url }) }; }
Когда подходит и когда нет
Когда уместны фоновые задачи с повторами
Когда это уместно
- Async из HTTP, вебхуков или cron, где сбои downstream ожидаемы
- Многошаговые задачи, где повтор всей job дорог или небезопасен
Когда лучше не трогать
- Синхронная работа <1 с без риска сбоя
Вопросы и ответы
Вопросы и ответы
Чем отличается от retry в BullMQ?
BullMQ повторяет целые job в Redis с воркером. Inquir — отдельные шаги пайплайна с чекпоинтами, без Redis и флота воркеров.
Разная политика retry на шаг?
Да. Счётчик и backoff на шаг. Flaky external API может retry агрессивнее, чем локальная валидация.
После исчерпания retry?
Прогон failed с полными логами. Ручной replay из истории или алерт оператору.