@workflow.defn / Workflow type | a registered function (@resonate.register, resonate.register("name", fn), #[resonate::function], resonate.Register(r, "name", fn)) |
@activity.defn / Activity | a plain function invoked via ctx.run(fn, args) |
workflow.execute_activity(fn, …, start_to_close_timeout=…) | yield ctx.run(fn, args) — no timeout policy required |
| Task Queue + Worker wiring | a worker group (only when you need distributed dispatch) |
executeChild / ExecuteChildWorkflow(ChildType, …) | ctx.rpc("name", args) or ctx.run(fn, args) — invoke by registered name; recursion is trivial |
Promise.all / asyncio.gather / parallel futures (fan-out) | start each non-blocking (ctx.beginRun / ctx.rfi / .spawn() / ctx.RPC), then await each |
defineSignal + setHandler + condition | one latent durable promise: p = ctx.promise() then await p |
defineQuery / query handler | delete — promise/result state is the source of truth |
handle.signal(sig) (external) | resonate.promises.resolve(id, value) (HTTP-addressable from anywhere) |
workflow.sleep / NewTimer | ctx.sleep(duration) |
| saga compensation stack + drain-on-catch | inline ctx.run(undo, …) in the error branch, guarded by what completed |
continueAsNew | bounded loop: a plain loop. Unbounded loop: ctx.detached(self, n+1) tail-recursion |