Inquir Compute · фоновые задачи

Фоновые задачи с повторами — без флота воркеров

Фоновые задачи падают: 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, который часто копируют неверно.

Повторы шагов пайплайна как примитив платформы

Каждый шаг пайплайна повторяется независимо при сбое. Завершённые шаги остаются чекпоинтами — перезапускается только упавший. Политика 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-работу, платформа повторяет упавшие шаги.

1

Принять и поставить в очередь

HTTP или вебхук возвращает 202. global.durable.startNew() с payload задачи.

2

Идемпотентные шаги

Каждый шаг проверяет dedupe-key до side effects. Структурированный выход для следующего шага.

3

Политика retry и алерт

Счётчик retry и backoff в конфиге пайплайна. Алерт при превышении порога failure rate.

Фоновая задача с retriable-шагами пайплайна

HTTP-хендлер ставит работу одной строкой. Шаги пайплайна повторяются независимо при сбое downstream.

jobs/enqueue-export.mjs
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' }) };
}
jobs/export-step.mjs (pipeline step — retried on failure)
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 из истории или алерт оператору.