Cloudflare Agents 从入门到精通
附录

§14 长任务与持久执行:Fiber 断点续跑

14.1 问题:DO 会被驱逐

Durable Object 会因闲置(约 70–140 秒)、代码更新、alarm 超时(15 分钟)被赶走。长任务跑一半被踢,怎么办?

14.2 runFiber:可中断可恢复

runFiber 执行前在 SQLite 登记,执行中持有心跳,用 ctx.stash() 写检查点。被驱逐后,下次激活触发 onFiberRecovered

class MyAgent extends Agent {
  async doWork() {
    await this.runFiber("my-task", async (ctx) => {
      const step1 = await expensiveOperation();
      ctx.stash({ step1 });                 // 检查点
      const step2 = await anotherOp(step1);
      this.setState({ ...this.state, result: step2 });
    });
  }

  async onFiberRecovered(ctx) {
    if (ctx.name !== "my-task") return;
    const snap = ctx.snapshot as { step1: unknown } | null;
    if (snap) {
      const step2 = await anotherOp(snap.step1); // 从检查点续
      this.setState({ ...this.state, result: step2 });
    }
  }
}

14.3 长任务不丢进度

客户端断开?Agent 继续跑。重连?从 SQLite 读回进度接着发。AIChatAgent 的流式输出也有自动续传。

// 长效任务:启动-休眠-回调 模式
await this.runFiber("research", async (ctx) => {
  const steps = ["search", "analyze", "synthesize"];
  const completed: string[] = [];
  for (const step of steps) {
    await executeStep(step);
    completed.push(step);
    ctx.stash({ completed }); // 每步存盘
  }
});
维度 普通 async runFiber 标叔的结论
被驱逐 进度丢 检查点续 长任务必用
客户端断开 可能中断 继续跑 体验好
复杂度
注意
stash() 每次完全替换快照(不是 merge)。恢复逻辑必须写在 onFiberRecovered,原 lambda 不可重放。

持久执行讲完。下一 Part 进工具与渠道:浏览器、沙箱、MCP、RAG、支付。