Durable Objects

作者 cloudflareb052c32bab7d无许可证3K 个星标收录于 2026年10月8日更新于 2026年10月8日仓库7天前更新

Build, debug, or review Cloudflare Durable Objects code for persistent state and coordination.

AI 生成的概览

指导构建、调试和审查用于有状态协调的 Cloudflare Durable Objects 代码。

功能
提供实现 Cloudflare Durable Objects 的说明和参考资料,涵盖存储、并发、RPC 方法、闹钟、WebSocket 处理器以及 Wrangler 配置。包含快速参考代码模式、关键规则、反模式以及 stub 创建示例,并附带关于规则、测试和 Workers 的参考文件。它指向 Cloudflare 文档以获取最新 API 细节。
适用场景
适用于创建新的 Durable Object 类、实现 RPC、闹钟或 WebSocket 处理器、审查现有 Durable Objects 代码、配置 Wrangler 绑定和迁移,或使用 Cloudflare 的 Vitest 集成编写测试。
运行要求
无脚本;仅包含说明和参考文档。需要网络访问以获取 Cloudflare 文档,并假定已有 Cloudflare Workers 项目,测试需要 Wrangler 和 Cloudflare Vitest 集成。

Durable Objects

Build stateful, coordinated applications on Cloudflare's edge using Durable Objects.

Retrieval Sources

Your knowledge of Durable Objects APIs and configuration may be outdated. Prefer retrieval over pre-training for any Durable Objects task.

Fetch the relevant doc page when implementing features.

When to Use

  • Creating new Durable Object classes for stateful coordination
  • Implementing RPC methods, alarms, or WebSocket handlers
  • Reviewing existing DO code for best practices
  • Configuring wrangler.jsonc/toml for DO bindings and migrations
  • Writing tests with Cloudflare’s Vitest integration
  • Designing sharding strategies and parent-child relationships

Reference Documentation

  • ./references/rules.md - Core rules, storage, concurrency, RPC, alarms
  • Testing reference - Current Vitest documentation, migration choices, and test selection
  • ./references/workers.md - Workers handlers, types, wrangler config, observability

Search: blockConcurrencyWhile, idFromName, getByName, setAlarm, sql.exec

Core Principles

Use Durable Objects For

NeedExample
CoordinationChat rooms, multiplayer games, collaborative docs
Strong consistencyInventory, booking systems, turn-based games
Per-entity storageMulti-tenant SaaS, per-user data
Persistent connectionsWebSockets, real-time notifications
Scheduled work per entitySubscription renewals, game timeouts

Do NOT Use For

  • Stateless request handling (use plain Workers)
  • Maximum global distribution needs
  • High fan-out independent requests

Quick Reference

Wrangler Configuration

jsonc
// wrangler.jsonc{  "durable_objects": {    "bindings": [{ "name": "MY_DO", "class_name": "MyDurableObject" }]  },  "migrations": [{ "tag": "v1", "new_sqlite_classes": ["MyDurableObject"] }]}

Basic Durable Object Pattern

typescript
import { DurableObject } from "cloudflare:workers";
export interface Env {  MY_DO: DurableObjectNamespace<MyDurableObject>;}
export class MyDurableObject extends DurableObject<Env> {  constructor(ctx: DurableObjectState, env: Env) {    super(ctx, env);    ctx.blockConcurrencyWhile(async () => {      this.ctx.storage.sql.exec(`        CREATE TABLE IF NOT EXISTS items (          id INTEGER PRIMARY KEY AUTOINCREMENT,          data TEXT NOT NULL        )      `);    });  }
  async addItem(data: string): Promise<number> {    const result = this.ctx.storage.sql.exec<{ id: number }>(      "INSERT INTO items (data) VALUES (?) RETURNING id",      data    );    return result.one().id;  }}
export default {  async fetch(request: Request, env: Env): Promise<Response> {    const stub = env.MY_DO.getByName("my-instance");    const id = await stub.addItem("hello");    return Response.json({ id });  },};

Critical Rules

  1. Model around coordination atoms - One DO per chat room/game/user, not one global DO
  2. Use getByName() for deterministic routing - Same input = same DO instance
  3. Use SQLite storage - Configure new_sqlite_classes in migrations
  4. Initialize in constructor - Use blockConcurrencyWhile() for schema setup only
  5. Use RPC methods - Not fetch() handler (compatibility date >= 2024-04-03)
  6. Persist first, cache second - Always write to storage before updating in-memory state
  7. One alarm per DO - setAlarm() replaces any existing alarm

Anti-Patterns (NEVER)

  • Single global DO handling all requests (bottleneck)
  • Using blockConcurrencyWhile() on every request (kills throughput)
  • Storing critical state only in memory (lost on eviction/crash)
  • Using await between related storage writes (breaks atomicity)
  • Holding blockConcurrencyWhile() across fetch() or external I/O

Stub Creation

typescript
// Deterministic - preferred for most casesconst stub = env.MY_DO.getByName("room-123");
// From existing ID stringconst id = env.MY_DO.idFromString(storedIdString);const stub = env.MY_DO.get(id);
// New unique ID - store mapping externallyconst id = env.MY_DO.newUniqueId();const stub = env.MY_DO.get(id);

Storage Operations

typescript
// SQL (synchronous, recommended)this.ctx.storage.sql.exec("INSERT INTO t (c) VALUES (?)", value);const rows = this.ctx.storage.sql.exec<Row>("SELECT * FROM t").toArray();
// KV (async)await this.ctx.storage.put("key", value);const val = await this.ctx.storage.get<Type>("key");

Alarms

typescript
// Schedule (replaces existing)await this.ctx.storage.setAlarm(Date.now() + 60_000);
// Handlerasync alarm(): Promise<void> {  // Process scheduled work  // Optionally reschedule: await this.ctx.storage.setAlarm(...)}
// Cancelawait this.ctx.storage.deleteAlarm();

Testing

Read the testing reference before configuring a suite or writing Durable Object tests. It routes to current setup, APIs, and examples and identifies the behavior to cover.

来源与署名

来源:cloudflare/skills位于skills/durable-objects提交b052c32

许可证: 无许可证

内容归原作者所有。SourceWeft 从公开仓库中收录这些内容。

举报或申请下架