Workflows
Workflows — устойчивые, долгоживущие операции, которые переживают падения и перезапуски. Они обеспечивают гарантии надёжности для критических бизнес-процессов: платежей, выполнения заказов, многошаговых согласований.
Зачем Workflows?
Функции эфемерны — если хост падает, выполняемая работа теряется. Workflows сохраняют состояние:
| Аспект | Функции | Workflows |
|---|---|---|
| Состояние | В памяти | Персистентное |
| Падение | Потеря работы | Возобновление |
| Длительность | Секунды-минуты | Часы-месяцы |
| Завершение | Best effort | Гарантированное |
Как работают Workflows
Код workflow выглядит как обычный Lua:
local funcs = require("funcs")
local time = require("time")
local result = funcs.call("app.api:charge_card", payment)
time.sleep("24h")
local status = funcs.call("app.api:check_status", result.id)
if status == "failed" then
funcs.call("app.api:refund", result.id)
end
Движок workflow перехватывает вызовы и записывает результаты. Если процесс падает, выполнение воспроизводится из истории — тот же код, те же результаты.
funcs.call(), time.sleep(), uuid.v4() и time.now() перехватываются, их результаты записываются. При воспроизведении возвращаются записанные значения вместо повторного выполнения.
Паттерны Workflows
Паттерн Saga
Компенсация при сбое:
local funcs = require("funcs")
local inventory = funcs.call("app.inventory:reserve", items)
if inventory.error then
return nil, inventory.error
end
local payment = funcs.call("app.payments:charge", amount)
if payment.error then
funcs.call("app.inventory:release", inventory.id)
return nil, payment.error
end
local shipping = funcs.call("app.shipping:create", order)
if shipping.error then
funcs.call("app.payments:refund", payment.id)
funcs.call("app.inventory:release", inventory.id)
return nil, shipping.error
end
return {inventory = inventory, payment = payment, shipping = shipping}
Ожидание сигналов
Ожидание внешних событий (решений по согласованию, вебхуков, действий пользователя):
local funcs = require("funcs")
funcs.call("app.approvals:submit", request)
local inbox = process.inbox()
local msg = inbox:receive() -- блокируется до прихода сигнала
if msg.approved then
funcs.call("app.orders:fulfill", request.order_id)
else
funcs.call("app.notifications:send_rejection", request)
end
Когда что использовать
| Сценарий | Выбор |
|---|---|
| Обработка HTTP-запросов | Функции |
| Трансформация данных | Функции |
| Фоновые задачи | Процессы |
| Состояние пользовательской сессии | Процессы |
| Real-time сообщения | Процессы |
| Обработка платежей | Workflows |
| Выполнение заказов | Workflows |
| Многодневные согласования | Workflows |
Запуск Workflows
Workflows порождаются так же, как процессы — через process.spawn() с другим хостом:
-- Spawn workflow на temporal worker
local pid = process.spawn("app.workflows:order_processor", "app:temporal_worker", order_data)
-- Отправка сигналов в workflow
process.send(pid, "update", {status = "approved"})
С точки зрения вызывающего API идентичен. Разница в хосте: workflows выполняются на temporal.worker, а не на process.host.
process.spawn(), они становятся дочерними workflows на том же провайдере, сохраняя гарантии надёжности.
Сбои и супервизия
Процессы могут работать как супервизируемые сервисы через process.service:
# Определение процесса
- name: session_handler
kind: process.lua
source: file://session_handler.lua
method: main
# Супервизируемый сервис, оборачивающий процесс
- name: session_manager
kind: process.service
process: app:session_handler
host: app:processes
lifecycle:
auto_start: true
restart:
max_attempts: 10
Workflows не используют деревья супервизии — ими автоматически управляет провайдер workflows (Temporal). Провайдер обрабатывает персистентность, повторы и восстановление.
Конфигурация
Определение процесса (порождается динамически):
- name: order_processor
kind: workflow.lua
source: file://order_processor.lua
method: main
modules:
- funcs
- time
Провайдер workflows:
- name: temporal_worker
kind: temporal.worker
client: app:temporal_client
task_queue: "orders"
lifecycle:
auto_start: true
См. Temporal для продакшен-инфраструктуры workflows.
См. также
- Функции — обработка запросов без состояния
- Модель процессов — фоновая работа с состоянием
- Супервизия — политики перезапуска процессов