Workflow

作者 get-convex6ca54f6e2e75無授權條款6 個星標收錄於 2026年10月8日更新於 2026年10月8日儲存庫今天更新

Build a durable multi-step pipeline on Convex where each step runs in order and is retried independently on failure (transcribe→summarize→email, ETL, order fulfillment, any 'do A then B then C, retry each' job). Use @convex-dev/workflow — do NOT hand-roll a chain of scheduler calls or a custom jobs table. TRIGGER on multi-step / pipeline / 'retry each step' / long-running orchestration requests.

AI 產生的概覽

指導在 Convex 上使用 @convex-dev/workflow 元件建立可持久化的多步驟管線,並獨立重試每個步驟。

功能
說明如何將 @convex-dev/workflow 元件接入 Convex 應用程式,並定義一個各階段都作為可持久化、可獨立重試步驟執行的工作流程。內容涵蓋預設與單一步驟重試行為的設定、啟動工作流程並查詢狀態,以及處理函式接收 step 而非 ctx 的規則。同時列出反模式,例如自行維護工作資料表並串接排程呼叫。
適用情境
適用於需要在 Convex 上進行有序多步驟編排的工作,例如先轉錄、再摘要、後寄送電子郵件,或 ETL、訂單履行,且每個步驟都需獨立重試並能承受當機。面向被描述為管線、多步驟、逐步重試或長時間執行編排的需求。
執行需求
已安裝 @convex-dev/workflow 元件的 Convex 專案;僅為說明文件,不含指令碼。電子郵件部分引用了 @convex-dev/resend 等相關元件。

Durable multi-step workflows → @convex-dev/workflow

When the task is "do step A, then B, then C, and retry each step independently if it fails" — a pipeline, ETL, or orchestration that must survive crashes — use the workflow component. Do NOT hand-roll it with a jobs table + chained ctx.scheduler.runAfter calls: that reinvents durability, loses per-step retry/backoff, and (measured) scores worse than a plain implementation. Copy this pattern.

Wire the component

ts
// convex/convex.config.tsimport { defineApp } from "convex/server";import workflow from "@convex-dev/workflow/convex.config";const app = defineApp();app.use(workflow);export default app;

Define the workflow — one step.run* call per stage, retried independently

ts
// convex/workflows.tsimport { WorkflowManager } from "@convex-dev/workflow";import { components, internal } from "./_generated/api";import { v } from "convex/values";
export const workflow = new WorkflowManager(components.workflow, {  // Per-step default: retry each failed step independently with backoff.  defaultRetryBehavior: { maxAttempts: 4, initialBackoffMs: 1000, base: 2 },  retryActionsByDefault: true,});
export const transcribeAndSummarize = workflow.define({  args: { url: v.string(), userEmail: v.string() },  handler: async (step, args): Promise<void> => {    // Each step.runAction is durable + independently retried. If summarize fails    // 3× then succeeds, transcribe is NOT re-run — completed steps are memoized.    const transcript = await step.runAction(internal.youtube.transcribe, { url: args.url });    const summary = await step.runAction(internal.llm.summarize, { transcript });    await step.runAction(internal.email.sendSummary, { to: args.userEmail, summary });  },});
  • The handler's first arg is step, not ctx. Call step.runAction / step.runMutation / step.runQuery with a codegen'd internal.* reference — never ctx.run* inside a workflow (that breaks durability/memoization).
  • Each step.run* is a durable checkpoint. On crash or retry, completed steps are replayed from their stored result, not re-executed — so steps must target internalAction/internalMutations that do the real work.
  • Override retry per step when one stage is flakier: step.runAction(ref, args, { retry: { maxAttempts: 6, initialBackoffMs: 500, base: 2 } }). Set { retry: false } for a step that must not repeat (already-idempotent external charge).
  • The actual work (the YouTube fetch, the LLM call, the email send) lives in ordinary internalActions — external APIs go in actions (see convex-external-apis), email via @convex-dev/resend (see crons).

Start it (and optionally track status)

ts
// from a public mutation/action the client calls:const workflowId = await workflow.start(  ctx,  internal.workflows.transcribeAndSummarize,  { url, userEmail },);// status later: await workflow.status(ctx, workflowId)  → cleanup: workflow.cleanup(ctx, workflowId)

Don't

  • ❌ A custom jobs/pipeline table + ctx.scheduler.runAfter chain to fake retries/ordering — that's what the component exists to replace.
  • ❌ ctx.runAction inside the workflow handler — use step.runAction or you lose durability.
  • ❌ Long synchronous work in one action to dodge steps — you lose independent retry and the 10-min action ceiling still applies per step.

來源與署名

來源:get-convex/convex-backend-skill位於skills/workflow提交6ca54f6

授權條款: 無授權條款

內容歸原作者所有。SourceWeft 從公開儲存庫中收錄這些內容。

檢舉或申請下架