Фоновые задачи на той же платформе, что и API
Отвечайте браузеру и мобильному клиенту за миллисекунды, а долгую работу выносите в пайплайны и очередь задач: ретраи при сбоях, идемпотентные записи и трассировки — как у синхронных вызовов.
Обновлено: 2026-06-28
Кратко
Суть ответа
Фоновые задачи на той же платформе, что и API. Функции становятся шагами пайплайна; платформа ведёт их выполнение так же, как синхронные вызовы, — фоновые задачи остаются доступными для поиска.
Когда подходит и когда нет
- Работа дольше нескольких секунд
- Всплески нагрузки
- Внешние API с непредсказуемой задержкой
На что обратить внимание
- Каждый сервис, изобретающий свою группу обработчиков в Redis, операционно расходится с тем, как работают остальные ваши serverless-функции.
- Без общей наблюдаемости фоновые задачи и пайплайны становятся чёрным ящиком рядом с REST-эндпоинтами.
Ситуация: нагрузка и где обычно ломается
Почему долгие HTTP-запросы ломают асинхронную работу
Долгая работа в потоке запроса упирается в таймауты API-шлюза и раздражает пользователей ещё до старта асинхронной задачи.
Шторм ретраев дублирует побочные эффекты, если хендлер фоновой задачи не идемпотентен.
Когда простых рецептов недостаточно
Почему самописные очереди прячут сбои
Каждый сервис, изобретающий свою группу обработчиков в Redis, операционно расходится с тем, как работают остальные ваши serverless-функции.
Без общей наблюдаемости фоновые задачи и пайплайны становятся чёрным ящиком рядом с REST-эндпоинтами.
Как Inquir помогает в этом сценарии
Одна поверхность для HTTP, async-задач и пайплайнов
Функции становятся шагами пайплайна; платформа ведёт их выполнение так же, как синхронные вызовы, — фоновые задачи остаются доступными для поиска.
Переиспользуйте секреты и сетевые настройки и для онлайн-трафика, и для офлайн-пайплайнов.
Сравнение
Таймаут HTTP-запроса и таймаут фоновой задачи
Фоновые задачи работают, когда HTTP перестаёт нести минуты работы. API-шлюз задаёт таймаут запроса; шаги пайплайна и задачи в очереди получают свой бюджет выполнения после того, как клиент освобождён.
| Критерий | Таймаут HTTP-запроса | Таймаут фоновой задачи / шага пайплайна |
|---|---|---|
| Что ограничивает | Открытое соединение клиент → шлюз → хендлер до отправки ответа | Вызов шага пайплайна или задачи в очереди после возврата HTTP-хендлера |
| Типичный потолок | Секунды — ~15 минут (например, Vercel 60–300 с, Lambda 900 с, Workers ~30 с CPU) | Таймаут на шаг — дольше HTTP-лимитов; цепочка шагов для многочасовой работы |
| Клиент ждёт? | Да — сокет открыт, пока хендлер не завершится или не сработает таймаут | Нет — клиент получает 202 или ID задачи; работа продолжается асинхронно |
| Ретраи | Провайдер может повторить весь HTTP-запрос — риск дублирования побочных эффектов | Ретраи по шагам с идемпотентными хендлерами, независимо от ACK-ответа |
| Наблюдаемость | Только логи запросов; оборванные прогоны — 504 или таймауты шлюза | История выполнения по шагам — рядом с синхронными вызовами, с поиском |
| Лучше подходит для | Валидация, аутентификация, быстрые чтения, постановка в очередь | Экспорты, массовая синхронизация, ML-пайплайны, многоэтапный ETL |
| Паттерн Inquir | HTTP-хендлер валидирует, вызывает global.durable.startNew(), возвращает 202 | Шаг пайплайна выполняется с общими секретами и тем же каталогом функций |
Что вы получаете на платформе
Паттерны фоновых задач, которые стоит стандартизировать
Веерная постановка
Одно событие — много задач с ясным владельцем.
Компенсация
Откат или эскалация при частичных сбоях.
Ограничение нагрузки
Регулируйте параллелизм под хрупкий приёмник.
Что сделать дальше, по шагам
Как проектировать фоновые задачи на Inquir Compute
Описать полезную нагрузку
Версионируйте схемы, чтобы обновления не ломали уже идущие задачи.
Сделать идемпотентным
Защита записей стабильными ключами.
Наблюдать
Сигналы на отложенные и проблемные сообщения, если платформа это показывает.
Пример кода
HTTP-ответ сразу, тяжёлая работа — в async-задаче
HTTP-хендлер возвращает 202 немедленно, не удерживая соединение. Хендлер задачи подхватывает работу с теми же секретами и наблюдаемостью.
export async function handler(event) { const { reportId, userId } = JSON.parse(event.body || '{}'); if (!reportId) return { statusCode: 400, body: JSON.stringify({ error: 'reportId required' }) }; // Enqueue the slow export job — returns immediately const { instanceId: jobId } = await global.durable.startNew('export-report', undefined, { reportId, userId }); // Client polls GET /export-status/:jobId or receives a webhook when done return { statusCode: 202, body: JSON.stringify({ jobId }) }; }
export async function handler(event) { const { reportId, userId } = event.payload; // Idempotency key — safe to retry const existing = await db.exports.findByReportAndUser(reportId, userId); if (existing?.status === 'done') return { url: existing.url }; const rows = await buildReport(reportId); const url = await storage.upload(rows, { key: `reports/${reportId}.csv` }); await db.exports.upsert({ reportId, userId, url, status: 'done' }); await notify(userId, { url }); return { url }; }
Когда подходит и когда нет
Выбирайте async, когда…
Когда это уместно
- Работа дольше нескольких секунд
- Всплески нагрузки
- Внешние API с непредсказуемой задержкой
Когда лучше выбрать другое
- Мгновенные чтения в рамках ваших соглашений по времени ответа
Вопросы и ответы
Вопросы и ответы
Достижима ли семантика «ровно один раз»?
Ориентируйтесь на идемпотентные хендлеры и ключи дедупликации; «ровно один раз» через сеть и хранилище на практике редко — проектируйте безопасно для как минимум одной доставки.
Когда отвечать HTTP 202?
Когда работа поставлена в очередь и есть идентификатор задачи или запуска — лучше, чем держать соединение до конца длинного экспорта.
Связь с расписаниями и вебхуками?
Пайплайны стартуют от расписания, HTTP, ручного или событийного триггера; вебхук может ответить 200 и поставить задачу в очередь — разные входы, та же схема оркестрации.