Статья A.S Groups

Cloudflare Workflows subscribe(): события выполнения без постоянного polling

Поток событий Cloudflare Workflows через subscribe без постоянного polling

Навигация по статье

Услуги A.S Groups

Нужен сайт, магазин или автоматизация?

Помогаю бизнесу запускать и дорабатывать WordPress-проекты: от посадочной страницы до WooCommerce, CRM и Telegram-уведомлений.

Обсудить проект Telegram
WordPress под ключ Лендинги, корпоративные сайты и структура под заявки. WooCommerce Интернет-магазины, каталог, оплата, доставка и интеграции. Доработка сайта Правки, скорость, формы, баги и развитие текущего проекта. CRM / Telegram / AI Автоматизация заявок, уведомлений и ручных процессов.

15 сентября 2026 года Cloudflare добавил потоковую подписку на события экземпляров Workflows. Вместо постоянного вызова проверки статуса приложение может использовать WorkflowInstance.subscribe() или API GET /subscribe и получать историю уже произошедших событий, а затем новые события по мере выполнения Workflow.

Это полезно для live-интерфейсов, уведомлений, интеграций и цепочек автоматизации, где важно быстро узнать, что шаг начался, завершился с ошибкой или весь Workflow дошёл до финального состояния — без отдельного таймера, который каждые несколько секунд опрашивает статус.

Что изменилось в Cloudflare Workflows

Раньше типичный внешний мониторинг строился вокруг периодической проверки состояния экземпляра Workflow. Теперь у конкретного instance можно открыть подписку на события. Cloudflare сначала возвращает доступные исторические события этого экземпляра, после чего подписка остаётся открытой и выдаёт новые события в реальном времени.

Подписка относится именно к одному экземпляру Workflow. Это удобно, когда приложение уже знает ID запуска и хочет следить за его прогрессом или передавать события дальше — например, в интерфейс оператора, Telegram, CRM или другую автоматизацию.

Базовый пример с WorkflowInstance.subscribe()

Экземпляр можно получить через binding и открыть поток событий:

const instance = await env.MY_WORKFLOW.get("report-123");

using subscription = await instance.subscribe();

while (true) {
  const { value, done } = await subscription.next();

  if (done) {
    break;
  }

  console.log(value.type, value);
}

Такой обработчик сначала прочитает доступную историю, а затем будет ждать новые события. После финального события экземпляра подписка завершается.

Какие события можно получать

Документация Cloudflare описывает события уровня Workflow и отдельных шагов. В зависимости от сценария можно отслеживать запуск и изменение состояния Workflow, начало и завершение шагов, ошибки, повторные попытки, ожидания и финальный результат.

К типичным событиям относятся состояния Workflow вроде queued, started, running, paused, waiting, completed, errored и terminated, а также события шагов — started, completed, errored, retries, sleeps, waits и rollback-сценарии.

Filter: подписываться только на нужные события

Если приложению не нужна полная временная шкала, в subscribe() можно передать фильтр типов событий. Например, сервис уведомлений может интересоваться только успешным завершением, ошибкой и принудительным завершением.

using subscription = await instance.subscribe({
  filter: [
    "workflow_completed",
    "workflow_errored",
    "workflow_terminated"
  ]
});

Фильтрация уменьшает объём логики на стороне клиента и позволяет не обрабатывать десятки промежуточных событий, если бизнесу важен только итог.

Cursor: как продолжить после разрыва соединения

Для надёжных интеграций важен cursor. Клиент сохраняет eventId последнего успешно обработанного события и при повторном подключении передаёт его как cursor. После этого Cloudflare начинает выдавать события, которые идут после указанного ID.

let lastEventId = 154;

using subscription = await instance.subscribe({
  cursor: lastEventId
});

Это позволяет строить возобновляемый consumer: если Worker, браузер или внешний сервис потерял соединение, не нужно начинать обработку всей истории заново. Важно сохранять cursor только после того, как событие действительно обработано вашим приложением.

Когда подписка завершается

Согласно документации Cloudflare, поток заканчивается после финальных событий экземпляра: workflow_completed, workflow_errored или workflow_terminated. Последующий вызов next() возвращает завершённое состояние iterator.

Это удобно для кода, который должен держать соединение только пока Workflow реально живёт, а затем освободить ресурсы автоматически.

Почему важно освобождать subscription

Подписка удерживает RPC-ресурс Workers. Cloudflare рекомендует корректно освобождать его, когда чтение больше не требуется. В JavaScript для этого удобно использовать using, как в примерах выше, либо явно закрывать ресурс в соответствии с API среды.

Если открыть большое количество подписок и не завершать их корректно, проблема будет уже не в polling, а в утечке долгоживущих ресурсов.

Что происходит с чувствительными данными шагов

Если выход шага помечен как чувствительный, Cloudflare не отдаёт его значение в поток событий в открытом виде. В документации для такого output используется значение [REDACTED]. Поэтому события удобно использовать для мониторинга состояния, но не стоит рассчитывать на них как на способ обхода правил защиты секретных данных.

subscribe() и обычный polling: в чём разница

Подход Как работает Когда удобен
Polling статуса Клиент периодически делает запрос и сравнивает состояние Редкие проверки, простые фоновые задачи
subscribe() Клиент получает историю и новые события одним потоком Live UI, уведомления, аудит выполнения, реакция на шаги
subscribe() + filter В поток попадают только выбранные типы событий Триггеры на completion/error/termination
subscribe() + cursor Поток возобновляется после последнего обработанного event ID Надёжные consumers и восстановление после разрыва

Практический сценарий: уведомление после завершения

Допустим, Workflow собирает отчёт, синхронизирует каталог или обрабатывает большой импорт. Вместо cron-проверки статуса можно открыть подписку только на финальные события. Когда приходит workflow_completed, приложение отправляет пользователю ссылку на результат; при workflow_errored — пишет ошибку в журнал и уведомляет ответственного.

В более сложной схеме consumer может запускать следующий Workflow, вызывать webhook CRM или обновлять статус задачи во внутренней панели.

Live-панель прогресса

Второй сценарий — интерфейс оператора. Backend открывает subscription для instance, переводит события в подходящий транспорт до фронтенда и показывает последовательность шагов. Пользователь видит, что задача не «зависла»: один шаг завершён, другой повторяется, третий ожидает внешний сигнал.

Такой интерфейс полезнее бесконечного индикатора загрузки, особенно для процессов, которые длятся минуты и состоят из нескольких внешних интеграций.

Исторические события и срок хранения

Подписка доступна, пока сохраняется состояние конкретного Workflow instance. Поэтому возможность поздно подключиться к истории зависит от retention Workflows.

На Free-плане документация указывает хранение состояния экземпляров до 3 дней. Для Paid Workflows период настраивается, а максимальный срок составляет 30 дней. Cloudflare также сообщал 10 сентября 2026 года, что для новых Paid Workflows значение по умолчанию изменено на 7 дней; существующие Workflows при этом не меняются автоматически.

HTTP API /subscribe

Вместе с методом Workers API Cloudflare анонсировал endpoint GET /subscribe. Это важно, если события должен читать не тот же Worker, который запустил процесс, а внешний сервис или другой компонент архитектуры.

При проектировании такого доступа стоит отдельно продумать авторизацию, срок жизни соединения, повторное подключение и хранение cursor. Сам поток событий не отменяет необходимость защищать API.

Не путать с account-level Event Subscriptions

Cloudflare имеет и другие механизмы событий. WorkflowInstance.subscribe() относится к событиям выполнения конкретного instance. Это не универсальная подписка на все события аккаунта Cloudflare и не замена отдельным Event Subscriptions для других продуктов.

Чек-лист внедрения

  • хранить ID конкретного Workflow instance;
  • решить, нужна вся история или только отдельные event types;
  • для надёжного consumer сохранять последний обработанный eventId;
  • при reconnect передавать его как cursor;
  • не считать [REDACTED] ошибкой — sensitive output скрывается намеренно;
  • корректно освобождать subscription/RPC-ресурс;
  • учитывать retention instance при позднем подключении;
  • логировать ошибки consumer отдельно от ошибок самого Workflow;
  • для внешнего API добавить собственную авторизацию и ограничения доступа.

Когда subscribe() особенно полезен

  • долгие импорты и экспорты;
  • синхронизация каталога между сайтом, складом и маркетплейсом;
  • генерация документов и отчётов;
  • AI-задачи из нескольких шагов;
  • CRM-автоматизации и webhook-цепочки;
  • операторские панели со статусом процесса;
  • уведомления об ошибке или завершении без cron/polling.

Официальные источники

Если Workflows используется как часть интеграционного слоя, полезно заранее определить, кто запускает процесс, кто слушает события и где хранится cursor. Для похожих задач можно посмотреть материал про архитектуру API на Cloudflare Workers и D1 и свежий разбор Hyperdrive для Python Workers.

Если нужно собрать такую автоматизацию под сайт, CRM, API или внутренний сервис, можно обсудить автоматизацию бизнес-процессов или прислать текущую схему интеграции. Архитектуру лучше выбирать после оценки источников событий, требований к задержке и поведения при повторном подключении.

Следующий шаг

Нужно решить похожую задачу?

Связать тему с автоматизацией, интеграциями, уведомлениями и serverless backend без утверждений, что стриминг событий заменяет все способы мониторинга.

Обсудить задачу

Источники

Обсуждение

Вопросы и комментарии

Можно уточнить детали статьи или поделиться своим опытом. Первый комментарий проходит проверку.

Оставить комментарий

Email не публикуется. Ссылки и HTML в тексте удаляются.

Мы используем приватную аналитику SlimStat, чтобы понимать, какие страницы полезны посетителям, и улучшать сайт. IP-адреса анонимизируются и хэшируются. Вы можете согласиться или отказаться от аналитики.
Cookies и конфиденциальность

Используем необходимые cookies, аналитику и данные форм, чтобы сайт работал корректно и заявки доходили.