Children and subflows
child awl 5 Declares a separate durable workflow this one may call and await.
-
formdeclaration -
positionstop-level
//! Call a separate durable workflow and await its result.
workflow grade_essay
input essay: String
outcome done: type Grade, route success
type Grade { score: Int }
child score_essay(essay: String) -> Grade
step grade
score_essay(essay: essay) -> grade
route done(grade) spawn awl 5 Starts a child workflow without waiting for it, so it can bind no result.
-
formstatement -
positionsstep-body
//! Start a child without waiting; it can bind no result.
workflow archive_report
input report_id: String
outcome done: type String, route success
child notify_archived(report_id: String) -> Nil
step archive
spawn notify_archived(report_id: report_id)
route done(report_id) subflow awl 5 Declares an inline reusable graph with typed parameters and exactly one outcome, compiled into this workflow.
-
formdeclaration -
positionstop-level
//! An inline reusable graph with typed parameters and one outcome.
workflow review_repo
input repo: String
outcome done: type Report, route success
type Report { summary: String }
worker reviewers
action inspect(target: String) -> Report
subflow review_once(target: String)
outcome out: type Report
step look
inspect(target: target) -> report
route out(report)
step review
review_once(target: repo) -> report
step publish
report |> route done An ordinary child call waits and binds the result. Spawn starts without waiting and cannot bind a result. The child must be deployed with a matching contract. A subflow’s invocation is the sole statement of a top-level step and may bind its outcome. It cannot sit inside a fork, loop, failure handler or substep. Subflows can nest but cannot recurse.
Wait and sleep
wait awl 10 Waits for a declared signal and binds it; a `timeout` makes that binding optional, because expiry is absence. Without one, the wait also guards a flow loop it sits on: no `max N visits` is needed.
-
formstatement -
positionsstep-body
//! Take delivery of the declared signal, binding its payload.
workflow hold_for_go
input build_id: String
signal go: Approval
outcome done: type String, route success
type Approval { approver: String }
step hold
wait go -> approval
route done(approval.approver + " released " + build_id) sleep awl 10 Sleeps for a duration on a durable timer.
-
formstatement -
positionsstep-body
//! Sleep on a durable timer; the run survives a restart mid-sleep.
workflow cool_down
input build_id: String
outcome done: type String, route success
step pause
sleep 30s
route done(build_id) A signal wait uses a declared receive contract. A timed wait handles its timeout path. Sleep creates a durable timer and releases execution capacity while waiting.
Failure handling
on awl 11 Opens a step failure handler, or names a signal that arms a workloop in its header.
-
formstatement -
positionsworkloop-header, step-body
//! `on failure` runs when the step faults, and must end in a route.
workflow publish_package
input name: String
outcome done: type String, route success
outcome failed: type String, route failure
worker registry
action publish(name: String) -> Nil
action yank(name: String) -> Nil
step publish
publish(name: name)
route done(name)
on failure
yank(name: name)
route failed("publish failed; yanked") An on-failure block receives errors from the fallible operations it guards. Keep the handler inside the compiler’s supported statement set: an untimed wait is accepted, while a loop, fork, timed wait or child spawn in that block is refused during bytecode compilation.
The reference overview lists every additional bytecode compilation restriction.