Raxol. Workflow. Async
(Raxol v2.6.0)
View Source
Asynchronous execution surface for Raxol.Workflow.Compiled graphs.
Wraps Raxol.Workflow.Runtime.invoke/3 in a separately-spawned
process and a per-run telemetry handler so callers can either:
- fire-and-forget a run and monitor for completion
(
async_invoke/3), or - consume the run's progress as a lazy
StreamofRaxol.Core.Events.CloudEventstructs (stream_events/3)
This module ships the synchronous-spawn shape. A
Raxol.Workflow.RunSupervisor (DynamicSupervisor) for production
hardening is a follow-up; the API here is supervisor-agnostic, so
swapping to a supervised spawn does not break existing callers.
The runtime emits telemetry events on [:raxol, :workflow, :run, _]
and [:raxol, :workflow, :node, _]; stream_events/3 attaches a
handler scoped to its run_id and converts each event into a CloudEvent
before pushing it onto the stream.
Summary
Functions
@spec async_invoke(Raxol.Workflow.Compiled.t(), any(), keyword()) :: {:ok, %{run_id: binary(), pid: pid(), ref: reference()}}
Spawn the run in a separate process and return a handle immediately.
Returns {:ok, %{run_id: binary, pid: pid, ref: reference}}. The
caller can:
Process.demonitor(ref, [:flush])if the result is no longer needed.receive{:DOWN, ref, :process, pid, reason}to detect completion.- subscribe to
[:raxol, :workflow, *]telemetry events filtered byrun_idfor progress updates.
The spawned process is not linked to the caller; a worker crash
arrives as a :DOWN message rather than a synchronous exit signal.
@spec async_resume(Raxol.Workflow.Compiled.t(), binary(), any(), keyword()) :: {:ok, %{run_id: binary(), pid: pid(), ref: reference()}} | {:error, :no_saver_configured | :no_checkpoint, nil}
Spawn a resume in a separate process and return a handle immediately.
Mirrors async_invoke/3 but for the resume path. Looks up the
latest checkpoint for run_id synchronously before spawning so the
resume preconditions surface as a regular error tuple rather than
hiding inside a normal-exit :DOWN message.
Returns {:ok, %{run_id, pid, ref}} on success or one of:
{:error, :no_saver_configured, nil}-- graph has no Saver{:error, :no_checkpoint, nil}-- no checkpoint forrun_id
@spec resume_events(Raxol.Workflow.Compiled.t(), binary(), any(), keyword()) :: Enumerable.t()
Resume a run and return a lazy Stream of CloudEvent structs.
Mirrors stream_events/3 but for the resume path. The stream
carries telemetry events emitted during the resume invocation only;
events emitted during the original (interrupted) run are not
replayed.
Preconditions (no saver, no checkpoint) raise ArgumentError from
the stream start function rather than yielding an empty stream that
the consumer would block on. Callers that want a tuple-shaped
preflight should use async_resume/4.
Accepts the same options as stream_events/3.
@spec stream_events(Raxol.Workflow.Compiled.t(), any(), keyword()) :: Enumerable.t()
Run the graph and return a lazy Stream of CloudEvent structs.
Each emitted telemetry event (run.started, node.started,
node.completed, etc.) is converted to a Raxol.Core.Events.CloudEvent
using the directive envelope and pushed onto the stream in the order
the runtime emits it. The stream terminates after the first run-level
terminal event (completed, interrupted, or failed).
Options
:timeout_ms- per-event receive timeout (default 60_000). The stream halts if no event arrives within the window.:source- CloudEvent source URI override; defaults toApplication.get_env(:raxol, :workflow_event_source, "raxol://workflow").
Any opts not consumed here are forwarded to Runtime.invoke/3.