Authoring
Everything you build a real workflow from. The app/workflows convention, child workflows, durable entities, queries and updates, events, webhooks and external tasks, versioning, and both config-driven and runtime-persisted scheduling.
Workflows & steps covers the primitive every workflow is built from. This section covers what you need once a single workflow is no longer enough.
Writing workflows
- app/workflows & make:workflow: the class-based convention. One
BaseWorkflowsubclass per file underapp/workflows, with astatic workflowconfig (name, version, input schema, singleton, onError routes, …), registered automatically at boot, constructor-injected through the container, and scaffolded bymake:workflow.
Composition
- Child workflows: call a workflow from a workflow.
Inner.start/ctx.childwaits for a result,Inner.dispatch/ctx.startChildstarts one without waiting,ctx.allfans out over a list (of child workflows or of steps), andctx.allSettleddoes the same without failing on a failed item.ctx.continueAsNewrestarts a long loop with a clean history. Pass a class for typed input and output, or a name string for a child in another runtime. - Durable entities: keyed virtual actors.
engine.registerEntitydefines handlers that run one at a time per key over durable state, exactly once. Drive them withengine.signalEntity/ctx.callEntity.
Talking to a running run
- Queries & updates: read a live run's state without affecting it (
ctx.setEvent+engine.getEvent), steer it with validated updates that can be rejected before they reach the run, and index runs with search attributes. - Events:
engine.publishEventresumes every run parked on a matchingctx.waitForEventand starts everyonEventsubscriber, with idempotent publishing, debounce/batch coalescing and buffered delivery. - Event-triggered workflows: start a workflow from an AdonisJS emitter event (
@OnEvent) or an@adonis-agora/diagnosticschannel (@OnDiagnostic), with the payload as input. - Durable webhooks:
ctx.webhook()creates a callback URL to hand to a third party inside a step. The run then suspends, using no compute, until the callback arrives. - External tasks & control primitives:
ctx.taskwithengine.completeTask/failTaskfor work a foreign system completes,ctx.transactionfor a step that checkpoints in the same transaction as its write, andctx.breakpointto pause a run for a human.
Keeping it running
- Versioning & determinism: how in-flight runs stay replay-safe across a deploy. Covers workflow versions for breaking changes, the
NonDeterminismErrorguard, deterministicctx.now/ctx.sideEffect, andctx.patchedfor an in-place change. - Scheduling: recurring workflows declared in
config/durable.ts(or colocated asstatic schedule), on a fixed interval or a DST-aware cron, started exactly once per window. - Persisted schedules:
engine.schedules, for schedules you create, update, pause, trigger and delete at runtime, stored in the state store (durable_schedules), and fired by the worker tick (node ace durable:workor the embedded worker) whenpersistedSchedulesis on. Safe with any number of workers.
Tenancy
The two isolation axes — namespace on the engine and partition on the transport — what each one actually partitions, and the boundary that keeps a store-less pod to its own runs.
app/workflows & make:workflow
The class-based authoring convention — a BaseWorkflow subclass per file under app/workflows with a static workflow config, auto-registered at boot, scaffolded by make:workflow. The parallel to @adonisjs/queue's app/jobs and make:job.