Current section

Files

Jump to
aion_flow src aion internal pump.gleam
Raw

src/aion/internal/pump.gleam

//// The workflow-side query pump loop around suspending awaits.
////
//// The engine answers workflow queries at yield points (AT-007 C20): when a
//// query is pending for the workflow, a suspending await returns the
//// sentinel `Error("aion_query:" <> json)` instead of resolving. `run`
//// recognises the sentinel, services the query through
//// `aion_flow_query_pump` (handler lookup, try/catch, reply), and re-enters
//// the same await, which re-resolves identically — pump iterations are
//// invisible to history and to replay. Every other result passes through
//// untouched.
import aion/internal/ffi
/// Run a suspending await thunk, servicing any pending queries the engine
/// surfaces as `aion_query:` sentinels before the await's own resolution.
///
/// The loop is tail-recursive: each serviced query is answered exactly once,
/// then the await is re-entered until it resolves with a non-sentinel
/// result. A query handler raise never crashes the workflow — the Erlang
/// pump converts it into a `reply_query_error` and the loop continues.
pub fn run(do: fn() -> Result(String, String)) -> Result(String, String) {
case do() {
Error("aion_query:" <> sentinel_payload) -> {
ffi.service_query(sentinel_payload)
run(do)
}
outcome -> outcome
}
}