castomFLOW
Открыть castomFLOW

Запуски, которым можно доверять

Автоматизацию никто не замечает, пока она не отправит что-то дважды

А потом замечают все. Четыре механизма на этой странице существуют потому, что сбои такого ПО всегда одни и те же четыре, и все они устранимы дизайном, а не старательностью.

Смоделируйте перед публикацией

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

Ничего не покидает систему. Не отправляется письмо, не выставляется счёт, не списывается плата, не записывается строка. Внешние вызовы фиксируются как намерения — с полезной нагрузкой, которая была бы отправлена, — чтобы вы могли проверить правильность маппинга до того, как это станет чьей-то проблемой.

Симуляции — это способ ответить на вопрос, который мешает людям включать автоматизацию: что она на самом деле сделает?

Симуляция · заказ 88 214Ничего не отправлено
  • 1Проверить адресСовпадение. Было бы записано 6 полей.
  • ?УсловиеЗаказ свыше 1 000 zł? Нет — 289,00 zł. Выбран короткий путь.
  • 3СчетБыл бы отправлен POST-запрос в систему выставления счетов. Полезная нагрузка показана полностью.
  • !Перехвачено здесьСтавка НДС взята из неверного поля. Обнаружено в симуляции, а не во входящих у бухгалтера.

Отправлено: ничегоСписано: ничего

Запуск проходит ту версию, на которой он начался

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

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

Новые запуски получают новую версию с момента публикации. Версия каждого запуска записана в самом запуске, поэтому на вопрос о поведении в марте есть ответ и в сентябре.

Редактирование во время работыv4 → v5
  • 1До2 918 запусков в процессе, все на v4. Некоторые в двухдневном ожидании.
  • 2Опубликовать v5Два шага переставлены, одно сообщение переписано.
  • 3ПослеЭти 2 918 завершают v4. Всё, что начинается с 11:40, выполняется на v5.
  • §Никтоне получил половину одного рабочего процесса и половину другого.

Версия записана в каждом запускеСтарые версии сохраняются

Повторы, которые не могут отправить дважды

Шаг — это чистая функция своих входных данных, и его эффекты фиксируются вместе с переходом запуска к следующему шагу. Не существует окна, в котором сообщение уже отправлено, а запуск об этом не знает.

В этом весь приём, и это структурное свойство, а не обещание. Воркер, убитый посреди шага — деплой, сбой, исчезнувшая машина, — оставляет запуск ровно там, где он был. Другой воркер подхватывает его и выполняет шаг заново. Поскольку эффект и переход фиксируются как одно целое, произошло либо и то и другое, либо ничего.

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

Воркер убит во время отправкиВосстановлено
  • 1Начинается шаг 5Отправить уведомление об отгрузке.
  • ✕Воркер умираетДеплой. Ничего не было зафиксировано.
  • 2ПодхваченоДругой воркер обнаруживает запуск всё ещё на шаге 5.
  • ✓Отправлено один разКлиент получил одно письмо, а не два.

Эффекты фиксируются вместе с переходомКлюч идемпотентности для каждого запуска и шага

Журнал, написанный для чтения человеком

Каждый запуск, каждый шаг, выбранная ветка и значение, которое её определило. Время выполнения каждого шага. Запрос и ответ каждого внешнего вызова с скрытыми учётными данными. Версия, на которой работал запуск. Где запуск ожидает и до какого времени.

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

Неудачные запуски собираются в одном месте с сгруппированной причиной, поэтому «сорок один сбой за ночь» превращается в «один поставщик возвращал 503 в течение девяти минут», а не в сорок одно отдельное расследование.

За ночь, сгруппировано41 сбой
  • 1Одна причинаAPI поставщика возвращал 503 с 02:41 до 02:50.
  • 2Что произошлоВсе 41 запущены повторно; 39 успешно со второй попытки.
  • 3ОсталосьДва остановлены и ждут человека. Оба перечислены вместе со строкой, на которой произошёл сбой.
  • §Не сорок одинрасследований. Одно — и решение по двум записям.

Учётные данные скрытыВерсия зафиксирована

Чего мы не утверждаем

Мы не публикуем показатель доступности на маркетинговой странице, потому что число без окна измерения и определения «доступен» — это украшение. Если он нужен вам договорно, спросите, и мы обсудим, к чему мы реально можем обязаться.

Мы также не можем сделать чужой API надёжным. Если поставщик недоступен, зависящий от него процесс ждёт, повторяет попытки и в конце останавливается с понятной причиной. Что мы можем обещать — так это то, что сбой будет виден, что он ничего не повредит и что возобновление не отправит сообщение повторно.

Об ожиданиях: запуск, ожидающий два дня, — это wake_at у запуска, а не задание, сидящее в очереди. Именно поэтому процесс может держать сто тысяч запусков в трёхнедельном ожидании, не затрачивая на это ничего, и почему число ожидающих запусков — не то, о чём вам приходится думать.

Запуск, о котором вы никогда не думаете, — это тот, который сработал.