Clojure Async Flow Guide
Быстрый старт
Библиотека flow отделяет бизнес-логику от развёртывания: топологии, исполнения, обмена сообщениями, жизненного цикла, мониторинга и обработки ошибок.
step-fn и процессы
Логика описывается функциями step-fn, которые flow заворачивает в процессы, крутящиеся в цикле. step-fn не работают с каналами напрямую и не хранят состояние, поэтому легко тестируются и переиспользуются.
step-fn имеет четыре арности:
describe (step-fn) → descriptor
Возвращает статическое описание :params
, :ins
, :outs
— карты имя → документация. Имена входов и выходов не должны пересекаться.
{:params {:size "Максимальный размер"}
:ins {:in "Входной канал"}
:outs {:out "Выходной канал"}}
init (step-fn arg-map) → init-state
Один раз вызывается при старте процесса; превращает параметры из flow-def в начальное состояние.
transition (step-fn state transition) → state'
Вызывается при переходах жизненного цикла (::flow/start
, ::flow/stop
, ::flow/pause
, ::flow/resume
). Используется для управления внешними ресурсами.
transform (step-fn state input msg) → [state' {out-id [msgs]}]
Вызывается для каждого входящего сообщения. Возвращает новое состояние и карту выходных сообщений. Выход может быть пустым, но каждое сообщение — не nil
. Исключения логируются в :error-chan
.
Состояние процесса
Карта с любыми ключами. Дополнительно:
::flow/pid
— идентификатор процесса::flow/in-ports
,::flow/out-ports
— карты cid → внешний канал (создаётся вinit
)::flow/input-filter
— предикат cid для фильтрации входных каналов
Хелперы
lift*->step
— изf(x) → coll
делает step-fn с одним входом и выходомlift1->step
— то же, ноf(x) → single-value
map->step
— из карты с ключами:describe
,:init
,:transition
,:transform
строит step-fn
Запуск процесса
Функция process
принимает step-fn и опции:
::workload
—:mixed
,:io
,:compute
:compute-timeout-ms
— таймаут для:compute
(по умолчанию 5000 мс)
Комментарии (74)
- Участники обсуждают, жив ли Clojure: сообщество стабильно, но менее хайповое; NuBank расширяет core-команду и нанимает Developer Advocate.
- core.async.flow предлагает декларативный, фиксированный граф каналов для «структурированной конкурентности»; ошибки и паузы можно отслеживать, но изменять топологию на лету пока нельзя.
- Сравнивают с GenStage (Elixir), Manifold, Trio и missionary/electric; можно использовать как OS-, так и green-потоки.
- JVM-тулчейн вызывает у новичков страх, но Leiningen/deps.edn упрощают работу, а отладка всё же возможна.
- Clojure-окосистема активно развивается: Babashka, XTDB, Dyna3 и другие проекты; язык недавно получил мажорный релиз и готовится к виртуальным потокам JVM.