Job Blockers
Jobs can depend on other job chains to complete before they start. A job with incomplete blockers starts as blocked and transitions to pending when all blockers complete.
const jobTypeRegistry = defineJobTypeRegistry<{ "fetch-data": { entry: true; input: { url: string }; output: { data: string }; }; "process-all": { entry: true; input: { ids: string[] }; output: { results: string[] }; blockers: [{ typeName: "fetch-data" }, ...{ typeName: "fetch-data" }[]]; // Wait for multiple fetches (tuple with rest) };}>();
// Start with blockers (transactionHooks required — see Transaction Hooks guide)const fetchBlockers = await withTransactionHooks(async (transactionHooks) => client.startJobChains({ transactionHooks, items: [ { typeName: "fetch-data", input: { url: "/a" } }, { typeName: "fetch-data", input: { url: "/b" } }, ], }),);await withTransactionHooks(async (transactionHooks) => client.startJobChain({ transactionHooks, typeName: "process-all", input: { ids: ["a", "b", "c"] }, blockers: fetchBlockers, }),);
// Access completed blockers in workerconst worker = await createInProcessWorker({ client, jobTypeProcessorRegistry: createJobTypeProcessorRegistry({ client, jobTypeRegistry, processors: { "process-all": { attemptHandler: async ({ job, complete }) => { const results = job.blockers.map((b) => b.output.data); return complete(() => ({ results })); }, }, }, }),});
const stop = await worker.start();Blocker References
Section titled “Blocker References”The example above uses nominal references — { typeName: "fetch-data" }. Blockers also support fixed tuple slots, variadic rest slots, and structural references ({ input: {...} }) that match any entry job type with a compatible input shape. Blocker outputs are fully typed in the processor based on the reference. See Job Type References for details and examples.
See examples/showcase-blockers for a complete working example demonstrating fan-out/fan-in and fixed blocker slots. See also Transaction Hooks and Chain Patterns.