Gadget 36:Durable Objects 深掘り

強整合性を持つステートフルな実行ユニット Durable Objects を深掘り

Durable Objects 深掘り

Cloudflare OS の「ワークスペース・Gadget」を支える Durable Objects(DO)を理解します。

目的

  • DO が「何が強く・何が苦手か」を正確に把握する
  • リアルタイム共同編集・状態管理の設計感を身につける

前提条件

  • Workers 基礎(35-workers-basics
  • 公式 Doc: https://developers.cloudflare.com/durable-objects/

DO とは

  • エッジ上の強整合性を持つ状態フルな実行ユニット
  • 特定のオブジェクトに対し、同時に 1 箇所でのみ実行(単一スレッド的)
  • 状態は Storage API で永続化(Key-Value のほか SQLite も可)
[Worker] --bind(CALLOUT)--> [Durable Object]  ... 状態を保持
   |                              |
   +-- 同一キーへの並列アクセスは DO が直列化

手順(最小構成)

1. Worker に DO を宣言

[[durable_objects.bindings]]
name = "COUNTER"
class_name = "Counter"

[[migrations]]
tag = "v1"
new_sqlite_classes = ["Counter"]   # SQLite ストレージを使う場合

2. DO クラスを実装

export class Counter {
  constructor(state, env) {
    this.state = state;
  }
  async fetch(request) {
    let value = (await this.state.storage.get("value")) || 0;
    value += 1;
    await this.state.storage.put("value", value);
    return new Response(String(value));
  }
}

3. Worker 側から呼び出す

async fetch(request, env, ctx) {
  const id = env.COUNTER.idFromName("global-counter");
  const obj = env.COUNTER.get(id);
  return obj.fetch(request);
}

CFOS との関係(理解の手がかり)

  • ワークスペース / Gadget ごとに DO が裏打ちされ、リアルタイム同時編集を実現
  • .wrangler/ は DO のローカル永続データ(16
  • 「複数人で同時に触れる」のは DO の強整合性のおかげ

よくある失敗

症状 原因 対処
状態が消える ストレージに保存していない storage.put を忘れない
並列処理で競合 DO の直列化を誤解 1 キー 1 DO を設計の基本に
マイグレーション失敗 migrations タグ不一致 クラス追加時に必ず migration を更新
コスト増 DO を細かく作りすぎ 粒度をまとめる(1 キー 1 DO の範囲で)

確認

次に読む