Canvas
chain, group, and chord — builder shorthands for sequential, parallel, and joined DAG shapes.
chain, group, and chord — builder shorthands for sequential, parallel, and joined DAG shapes.
Three shorthands on the workflow builder. Each
adds ordinary .step() nodes with the after wiring filled in for you, returns
the same builder, and composes freely with hand-written steps. For worked
examples, see the Canvas guide.
const handle = queue.workflows
.define("etl")
.chain([
{ name: "extract", task: "extractTask", args: ["s3://bucket/in"] },
{ name: "transform", task: "transformTask" },
{ name: "load", task: "loadTask" },
])
.submit();CanvasStepEvery canvas helper takes CanvasStep objects — a node name, its task, and any
step option except after,
which the helper manages:
interface CanvasStep {
name: string;
task: string;
args?: unknown[];
queue?: string;
maxRetries?: number;
timeoutMs?: number;
priority?: number;
condition?: "on_success" | "on_failure" | "always";
compensate?: string;
cache?: boolean | { ttlMs?: number };
}chainchain(steps: CanvasStep[], options?: { after?: string | string[] }): thisWires steps sequentially — each depends on the one before it. The first step
runs after options.after, or as a root when omitted.
queue.workflows
.define("etl")
.chain([
{ name: "extract", task: "extractTask" },
{ name: "transform", task: "transformTask" },
{ name: "load", task: "loadTask", maxRetries: 5 },
])
.submit();groupgroup(steps: CanvasStep[], options?: { after?: string | string[] }): thisAdds steps in parallel — no dependencies between them. Every member runs
after options.after, or as roots when omitted.
queue.workflows
.define("notify")
.step("render", "renderMessage")
.group(
[
{ name: "email", task: "sendEmail" },
{ name: "sms", task: "sendSms" },
],
{ after: "render" },
)
.submit();chordchord(
steps: CanvasStep[],
callback: CanvasStep,
options?: { after?: string | string[] },
): thisA parallel steps group joined by callback, which depends on every group
member and runs once they all complete. With an empty group the callback falls
back to options.after, so it still chains after its declared prerequisites.
queue.workflows
.define("report")
.chord(
[
{ name: "q1", task: "queryRegion", args: ["east"] },
{ name: "q2", task: "queryRegion", args: ["west"] },
],
{ name: "merge", task: "mergeTask" },
)
.submit();callback runs with its own args, not the group members' return values. To
aggregate results, use fanOut/fanIn
instead — fanIn's task receives [childResult, …] as its single argument.
Canvas helpers build a normal DAG, so there is no canvas-specific submit path —
finish with .submit() (or .build() to reuse the spec as a
sub-workflow) and run a worker to
execute it.