Skip to content

非公式本サイトは非公式の日本語ドキュメントであり、Cloudflare 公式サイトではありません。最新情報はdevelopers.cloudflare.comをご確認ください。

Durable Object クラスの exports

最終更新 Markdown で表示Agent セットアップ

Wrangler 設定ファイルexports フィールドは、Durable Object クラス のライフサイクルを宣言的に管理する方法です。Worker がエクスポートする各 Durable Object クラスと、それがライブか、削除済みか、名前変更済みか、転送済みかを宣言します。Cloudflare は、その宣言を、すでに Worker 向けにプロビジョニング済みの名前空間と照合します。

このページでは、次の操作を説明します。

  • Durable Object クラスを 作成 する。
  • Durable Object クラスとそのデータを 削除 する。
  • Durable Object クラスを 名前変更 する。
  • Durable Object クラスを Worker 間で 転送 する。

exports の仕組み

exports を宣言した Worker をデプロイすると、Cloudflare は次の 3 つの情報源を比較します。

  1. コード — Worker が実際にエクスポートしている Durable Object クラスの集合です。
  2. exports 設定 — 各クラスについて宣言した内容です。
  3. プロビジョニング済みの状態 — この Worker にすでに存在する Durable Object 名前空間です。

コードにだけあるクラスは、exports で宣言するまで無視されます。Cloudflare は名前空間を暗黙にはプロビジョニングしません。そのほかの不一致(コードにクラスがないライブエントリや、対応するエントリがないプロビジョニング済み名前空間など)は、構造化されたエラーとして表面化するか、意図が明確な場合は Cloudflare が代わりに適用する操作になります。

最小の exports ブロックでは、各 Durable Object クラスをライブエントリとして宣言します。

{
	"durable_objects": {
		"bindings": [
			{
				"name": "MY_DURABLE_OBJECT",
				"class_name": "MyDurableObject",
			},
		],
	},
	"exports": {
		"MyDurableObject": {
			"type": "durable-object",
			"storage": "sqlite",
		},
	},
}
[[durable_objects.bindings]]
name = "MY_DURABLE_OBJECT"
class_name = "MyDurableObject"

[exports.MyDurableObject]
type = "durable-object"
storage = "sqlite"

削除、名前変更、転送などの破壊的な操作を宣言するには、エントリの state を tombstone(終了状態を表すエントリ)の一種に変えます。クラス名はそのままです。値は、既存の名前空間をどうするかを Cloudflare へ伝えます。

操作 state 必須フィールド
新しいクラスを定義する(デフォルト) "created"(または省略) storage
クラスを削除する "deleted" (なし)
クラスを名前変更する "renamed" renamed_to
クラスを別の Worker へ転送する "transferred" transferred_to
別の Worker からの転送を受け取る "expecting-transfer" storagetransfer_from

以降の各節で操作を詳しく説明し、スキーマ全体は exports 設定リファレンス を参照します。

Durable Object クラスを定義する

新しい Durable Object クラスを定義するには、クラス名をキーにしたエントリを exports に追加し、storage"sqlite" に設定します。

  1. クラスを Worker のコードに追加し、エクスポートします。

    src/index.tsts
    import { DurableObject } from "cloudflare:workers";
    
    export class MyDurableObject extends DurableObject {
      // ...
    }
  2. クラスのバインディングを追加します(Worker が env 経由でアクセスする場合)。あわせて、クラスを exports で宣言します。

    {
      "durable_objects": {
        "bindings": [
          {
            "name": "MY_DURABLE_OBJECT",
            "class_name": "MyDurableObject"
          }
        ]
      },
      "exports": {
        "MyDurableObject": {
          "type": "durable-object",
          "storage": "sqlite"
        }
      }
    }
    [[durable_objects.bindings]]
    name = "MY_DURABLE_OBJECT"
    class_name = "MyDurableObject"
    
    [exports.MyDurableObject]
    type = "durable-object"
    storage = "sqlite"
  3. Worker をデプロイします。

    npx wrangler deploy

最初のデプロイ時に、Cloudflare はそのクラス向けの名前空間をプロビジョニングします。同じエントリでの以降のデプロイでは、名前空間は変わりません。エントリは、クラスがまだライブであることを確認するだけです。

Durable Object クラスを削除する

Durable Object クラスを退役させるには、ライブエントリを deleted tombstone に置き換えます。クラスを削除すると、その名前空間と 保存済みデータはすべて完全に削除 されます。ソフトデリートではありません。

  1. Worker のコードからクラスを削除します。

  2. durable_objects.bindings から、そのクラスのバインディングを削除します。

  3. そのクラスの exports エントリを deleted tombstone に変えます。

    {
      "exports": {
        "OldDurableObject": {
          "type": "durable-object",
          "state": "deleted"
        }
      }
    }
    [exports.OldDurableObject]
    type = "durable-object"
    state = "deleted"
  4. Worker をデプロイします。

    npx wrangler deploy

deleted tombstone には、デプロイ時に次の 2 つの前提条件が適用されます。

  • クラスが Worker のコードに含まれていてはなりません。実行時のバインディングが削除済み名前空間へ解決してしまうため、Cloudflare はまだ出荷されているクラスの名前空間を削除しません。
  • アカウント内のほかの Worker が、その名前空間へバインドしていてはなりません。別の Worker がまだクラスへバインドしている場合、デプロイは tombstone_delete_blocked_by_external_bindings で拒否され、参照しているスクリプトの一覧が返ります。先にそれらの Worker からバインディングを外して再デプロイし、そのあとで自分のデプロイを再実行します。

名前空間が削除されると、tombstone は失効します。Cloudflare はこれを 照合結果 で報告し、エントリを removable_entries に載せるので、exports から安全に削除できます。

Durable Object クラスを名前変更する

Durable Object クラスの名前変更は、同じ Worker 内で、あるクラスから別のクラスへ保存済みデータを移します。名前変更には次が必要です。

  • 古いクラス名をキーにした renamed tombstone。renamed_to は新しいクラス名を指します。
  • 同じ exports マップ内に、新しいクラス名のライブエントリ(データの着地先)があること。

古いクラスがコードに残っていない新規デプロイなら、デプロイは 1 回で足ります。

{
	"exports": {
		"OldName": {
			"type": "durable-object",
			"state": "renamed",
			"renamed_to": "NewName"
		},
		"NewName": {
			"type": "durable-object",
			"storage": "sqlite"
		}
	}
}
[exports.OldName]
type = "durable-object"
state = "renamed"
renamed_to = "NewName"

[exports.NewName]
type = "durable-object"
storage = "sqlite"

名前変更が適用されると、名前空間のクラス名は NewName に更新されます。新しいクラス名を参照する実行時バインディングは、同じデータへ解決します。

名前変更中のダウンタイムを避ける

Durable Object クラスの名前変更では、ランタイム層で完全にはアトミックでない 2 つの更新が起きます。名前空間のクラスポインターと、クラスをエクスポートする Worker コードです。デプロイのロールアウト中、片方の更新がもう片方より数秒先に見えることがあります。このあいだの実行時エラーを避けるには、3 回のデプロイによる名前変更 を使います。

  1. 新しい名前を古いクラスへエイリアスする。 コードでは新しいクラス名を正規のクラスとして追加し、古い名前でも再エクスポートして、既存インスタンスが解決し続けられるようにします。

    src/index.tsts
    import { DurableObject } from "cloudflare:workers";
    
    export class NewName extends DurableObject {
      // ...
    }
    export { NewName as OldName };

    exports は変えません。デプロイします。

  2. エイリアスを残したまま名前変更を適用する。 exports を更新し、renamed tombstone と新しいライブエントリを追加します。

    {
      "exports": {
        "OldName": {
          "type": "durable-object",
          "state": "renamed",
          "renamed_to": "NewName"
        },
        "NewName": {
          "type": "durable-object",
          "storage": "sqlite"
        }
      }
    }
    [exports.OldName]
    type = "durable-object"
    state = "renamed"
    renamed_to = "NewName"
    
    [exports.NewName]
    type = "durable-object"
    storage = "sqlite"

    デプロイします。Cloudflare は名前変更を適用し、tombstone_class_still_in_code の情報通知を出します。これは想定どおりで、安全なロールアウトパターンであることを示します。

  3. エイリアスを削除する。 前のデプロイが完全にロールアウトしたら、コードから OldName エイリアスを削除します。

    src/index.tsts
    import { DurableObject } from "cloudflare:workers";
    
    export class NewName extends DurableObject {
      // ...
    }

    exports は変えません。デプロイします。OldName tombstone は失効し、Cloudflare はそれを removable_entries に載せます。次の設定編集で、exports からエントリを削除できます。

renamed_to の対象は、次を満たす必要があります。

  • 有効な JavaScript 識別子であり、元のクラス名と異なること。
  • 同じ exports マップ内にライブエントリ(state: "created" または省略)として存在すること。別の tombstone を指す、または欠落している renamed_to は拒否されます。
  • この Worker 上で、同じ名前の既存名前空間と衝突しないこと。対象名ですでに名前空間がある場合は、先のデプロイでその名前空間自身の deleted tombstone により削除します。

Durable Object クラスを Worker 間で転送する

転送は、既存の Durable Object 名前空間を、同じアカウント内のある Worker(ソース)から別の Worker(ターゲット)へ移します。2 つの Worker が協調する必要があるため、転送は複数回のデプロイになります。

ターゲット Worker は、ソース Worker を指名する expecting-transfer エントリを宣言します。ソース Worker は、ターゲット Worker を指名する transferred tombstone を宣言します。実際の受け渡しは、ソース Worker のデプロイが着地したときに確定します。

推奨する順序は、4 回のデプロイです。

  1. ソース Worker — 初期状態。 ソースは MyDO をライブクラスとして宣言します。ほかはまだ変わっていません。

    {
      "exports": {
        "MyDO": { "type": "durable-object", "storage": "sqlite" }
      }
    }
    [exports.MyDO]
    type = "durable-object"
    storage = "sqlite"
  2. ターゲット Worker — 転送を受け取る。 ターゲットはコードに MyDO を追加し、ソース Worker を指名する expecting-transfer エントリを宣言します。この段階では、ターゲットに MyDOdurable_objects.bindings エントリを 追加しないでください。このフェーズでは、Cloudflare は自己参照バインディングをソースの名前空間経由ではルーティングしません。

    {
      "exports": {
        "MyDO": {
          "type": "durable-object",
          "state": "expecting-transfer",
          "storage": "sqlite",
          "transfer_from": "source-worker"
        }
      }
    }
    [exports.MyDO]
    type = "durable-object"
    state = "expecting-transfer"
    storage = "sqlite"
    transfer_from = "source-worker"

    ターゲットをデプロイします。Cloudflare は保留中の転送を記録し、照合結果Transfer pending 通知を出します。

  3. ソース Worker — 転送を確定する。 ソースの MyDO エントリを、ターゲット Worker を指名する transferred tombstone に変えます。クラスは当面ソースのコードに残します。

    {
      "exports": {
        "MyDO": {
          "type": "durable-object",
          "state": "transferred",
          "transferred_to": "target-worker"
        }
      }
    }
    [exports.MyDO]
    type = "durable-object"
    state = "transferred"
    transferred_to = "target-worker"

    ソースをデプロイします。Cloudflare は保留中の転送と照合し、名前空間をアトミックにターゲット Worker へ付け替えます。照合結果は Transferred (committed): MyDO → target-worker と報告します。

    転送の確定後もソース Worker が MyDO へアクセスする必要がある場合は、durable_objects.bindings エントリを更新し、script_name でターゲット Worker を指します。

    {
      "durable_objects": {
        "bindings": [
          {
            "name": "MY_DURABLE_OBJECT",
            "class_name": "MyDO",
            "script_name": "target-worker"
          }
        ]
      }
    }
    [[durable_objects.bindings]]
    name = "MY_DURABLE_OBJECT"
    class_name = "MyDO"
    script_name = "target-worker"

    ソース Worker が MyDO へアクセスしなくなった場合は、ソース Worker のコードから MyDO を削除するときに、バインディングも削除します。

  4. ターゲット Worker — クラスをバインドする。 ソースのデプロイが完全にロールアウトしたら、MyDOdurable_objects.bindings エントリを付けてターゲットを再デプロイします。バインディングは、ターゲット Worker 上の名前空間へ解決します。

    {
      "durable_objects": {
        "bindings": [
          {
            "name": "MY_DURABLE_OBJECT",
            "class_name": "MyDO"
          }
        ]
      },
      "exports": {
        "MyDO": { "type": "durable-object", "storage": "sqlite" }
      }
    }
    [[durable_objects.bindings]]
    name = "MY_DURABLE_OBJECT"
    class_name = "MyDO"
    
    [exports.MyDO]
    type = "durable-object"
    storage = "sqlite"

受け渡しが全体にロールアウトしたら、ソース Worker のコードから MyDO を削除し、ソースの exports マップから transferred tombstone を削除できます。アカウント内のほかの Worker が、まだソース上の MyDO へバインドしているあいだは、照合結果がそれらを referencing_scripts に載せます。ソースの tombstone を削除する前に、各 Worker を再デプロイし、バインディングをターゲットへ付け替えてください。

保留中の転送をキャンセルする

保留中の転送は、ソース Worker が transferred tombstone で確定するか、ターゲット Worker が expecting-transfer エントリを外してキャンセルするまで残ります。キャンセルするには、そのエントリなし(または通常のライブエントリへ置き換えて)ターゲットを再デプロイします。Cloudflare は保留レコードを削除し、ソース Worker は名前空間を保持します。

転送の制約

  • 両方の Worker が、同じ Cloudflare アカウント内にある必要があります。
  • dispatch-namespace をまたぐ転送はサポートされません。ソースとターゲットの Worker は、同じ dispatch-namespace コンテキスト内(またはどちらも dispatch namespace の外)にある必要があります。
  • ターゲット Worker が同時に持てる、クラスごとの保留中フェーズ 1 ヒントは 1 つだけです。保留中の転送を別のソースへ付け替えるには、先に現在の保留中転送をキャンセルします。

ストレージバックエンド

ライブエントリ(state: "created"state: "expecting-transfer")は、storage の値を宣言する必要があります。

  • "sqlite" は SQLite ストレージバックエンドを選びます。新しい名前空間では推奨され、使える唯一の経路です。SQLite バックエンドの名前空間は SQLPoint-in-Time Recovery、およびより高いオブジェクトあたりのストレージ上限に対応します。
  • "legacy-kv" はキーバリューストレージバックエンドを選びます。Cloudflare がこの値を受け付けるのは、すでにキーバリューストレージでプロビジョニング済みの名前空間だけです(通常は、SQLite がデフォルトになる前に 従来の migrations 配列 で始めた Workers)。exports 経由で 新しい キーバリューバックエンドの名前空間を作ることはできません。

名前空間が存在したあと、ストレージの種類は変更できません。プロビジョニング済み名前空間の sqlitelegacy-kv を切り替える exports の変更は、storage_type_mismatch エラーで拒否されます。ストレージバックエンドを本当に変えるには、deleted tombstone で名前空間を削除し、新しいバックエンドで再プロビジョニングします(そのあいだデータはすべて失われます)。

照合結果を読む

デプロイが Durable Object クラスのライフサイクル変更を適用すると、wrangler deployDurable Object exports reconciliation ブロックを出力します。照合が警告、情報通知、または削除可能なエントリを出したときも、このブロックが出ます。変更がなく通知もない場合、Wrangler はブロックを出しません。

典型的な出力は次のとおりです。

Durable Object exports reconciliation:
  Created: ChatRoom
  Renamed: OldRoom → ChatRoom
  Transferred (committed): Widget → target-worker
  Transfer pending: Incoming ← source-worker

  Info:
    [tombstone_class_still_in_code] OldRoom: Tombstone of type 'renamed' applied. Class 'OldRoom' is still exported in code; this is the supported pattern for zero-downtime rename rollouts.
    [stale_tombstone] OldGone: Tombstone of type 'deleted' for class 'OldGone' has no effect (no namespace exists with this class name). Safe to remove from `exports`.

  Safe to remove from `exports`: OldGone

ブロックには 4 つの節があります。

  • 操作行CreatedUpdatedDeletedRenamedTransferredTransfer pending)は、このデプロイで Cloudflare が適用した変更を報告します。
  • 警告(黄色)は、調査すべきだがデプロイは止めない状態を示します。警告シナリオの集合は将来用に予約されており、現在の Cloudflare デプロイでは出力されません。
  • 情報(薄い表示)は、ブロックしない通知です。もう適用されない失効 tombstone と、ソースクラスがまだコードにある状態で適用された tombstone(ゼロダウンタイムロールアウトのサポート対象パターン)です。
  • exports から安全に削除できる項目 は、失効していて、アカウント内のほかの Worker がソースクラスへバインドしていない tombstone エントリを列挙します。次の設定編集で、これらのエントリを exports マップから削除できます。

情報エントリには referencing_scripts 一覧が付くことがあります。影響を受ける名前空間へ、まだバインディングが解決している、アカウント内のほかの Worker です。tombstone を削除する前に、それらの Worker を新しいクラス名へバインディングを付け替えて再デプロイしないと、バインディングが孤立します。

デプロイが失敗した場合、出力はクラスごとに構造化されたエラーを示します。

✘ [orphaned_provisioned_namespace] class 'Bar': A namespace exists for 'Bar' but no `exports` entry declares it.
    Suggestion: add an `exports` entry for 'Bar', or add a `deleted` tombstone to remove the namespace.
    Referencing scripts: worker-foo, worker-bar

1 回のデプロイで出たクラス単位のエラーはまとめて報告されるので、1 往復で直せます。シナリオの一覧は エラーリファレンス を参照してください。

失効した tombstone とクリーンアップ

tombstone は、適用しても状態が変わらないときに 失効 します。たとえば、名前空間がすでに削除されたクラス向けの deleted tombstone や、名前変更がすでに着地したあとの renamed tombstone です。

Cloudflare は、tombstone が失効しているデプロイのたびに stale_tombstone 情報通知を出します。exports からエントリを削除するまで続きます。通知は意図的に繰り返され、クリーンアップを忘れないようにします。

名前変更と転送の tombstone では、Cloudflare はアカウント内のほかの Worker のうち、durable_objects.bindings がまだソースのクラス名を参照しているものも列挙します。これらは情報通知の referencing_scripts に出ます。referencing_scripts が空でないあいだに tombstone を削除すると、それらのバインディングが孤立する可能性があります。先に参照側 Worker を再デプロイし、バインディングを新しいクラスへ付け替えてください。

照合結果の先頭付近にある「Safe to remove from exports」行は、referencing_scripts が空の失効 tombstone をすべて指名します。この一覧を、「今削除してよい」公式の手がかりとして使います。

環境、dispatch namespace、プレビュー

exports は Wrangler 設定ファイルのトップレベルで指定でき、環境 ごとに上書きできます。

{
	// top-level exports apply to the default environment
	"exports": {
		"MyDO": { "type": "durable-object", "storage": "sqlite" }
	},
	"env": {
		"staging": {
			// override for the staging environment
			"exports": {
				"MyDO": { "type": "durable-object", "storage": "sqlite" }
			}
		}
	}
}
[exports.MyDO]
type = "durable-object"
storage = "sqlite"

[env.staging.exports.MyDO]
type = "durable-object"
storage = "sqlite"

exports をトップレベルだけに宣言した場合、名前付き環境は同じ値を継承します。各環境は独自のプロビジョニング済み名前空間を持つため、tombstone は宣言した環境内にだけ適用されます。

プレビューデプロイdispatch namespace も同じ規則です。dispatch-namespace をまたぐ転送はサポートされません。transferred / expecting-transfer の組のソースとターゲット Worker は、同じ dispatch-namespace コンテキスト内(またはどちらも dispatch namespace の外)にある必要があります。

exports 設定リファレンス

exports フィールドは、Durable Object クラス名をキーにしたマップです。各値はオブジェクトで、フィールドは state に依存します。

  • type string 必須

    • Durable Object クラスのエントリでは、これを "durable-object" に設定します。
  • state string 任意

    • ライフサイクルの状態です。"created"(デフォルト、省略可)、"deleted""renamed""transferred""expecting-transfer" のいずれかです。
  • storage string 条件付き

    • state"created" または "expecting-transfer" のときに必須です。"sqlite"(推奨。新しい名前空間で有効な唯一の値)または "legacy-kv"(既存のキーバリューバックエンド名前空間のみ)のいずれかです。tombstone の状態では使えません。
  • renamed_to string 条件付き

    • state"renamed" のときに必須です。転送先のクラス名です。有効な JavaScript 識別子であり、元のクラス名と異なり、同じ exports マップ内にライブエントリとして存在する必要があります。
  • transferred_to string 条件付き

    • state"transferred" のときに必須です。名前空間を受け取るターゲット Worker の名前です。
  • transfer_from string 条件付き

    • state"expecting-transfer" のときに必須です。名前空間の転送元であるソース Worker の名前です。

次の表は、各 state で使えるフィールドと使えないフィールドです。

state 必須 使用不可
"created"(デフォルト) storage renamed_totransferred_totransfer_from
"deleted" (なし) storagerenamed_totransferred_totransfer_from
"renamed" renamed_to storagetransferred_totransfer_from
"transferred" transferred_to storagerenamed_totransfer_from
"expecting-transfer" storagetransfer_from renamed_totransferred_to

エラーリファレンス

照合でデプロイが失敗すると、Cloudflare はクラスごとに 1 件のエラーを返します。構造化された scenario タグ、人が読めるメッセージ、該当する場合は suggestionreferencing_scripts 一覧が付きます。

シナリオ 意味 対処方法
provisioned_class_missing_from_config Worker のコードがまだエクスポートしているクラス向けの名前空間があるのに、exports にそのエントリがありません。 名前空間を残すならライブエントリ(state: "created")を追加します。退役させるなら tombstone(deletedrenamed、または transferred)を追加します。
config_export_not_in_code ライブエントリが、Worker のコードがエクスポートしていないクラスを宣言しています。 クラスをコードに追加するか、エントリを tombstone に置き換えます。
config_references_nonexistent_class ライブエントリが、コードにもプロビジョニング済みでもないクラスを宣言しています。 エントリを削除するか、クラスを Worker のコードに追加します。
orphaned_provisioned_namespace コードにも宣言にもないクラス向けの名前空間があります。 そのクラスの tombstone を追加するか、クラスをコードと exports に戻します。
invalid_export exports エントリの構造が不正です。たとえば、新しい名前空間に legacy-kv を要求している、または 1 つのクラスが複数のプロビジョニング済み名前空間に対応している場合です。 エントリを直します。新しい名前空間では "storage": "sqlite" を使うか、deleted または renamed tombstone で重複を解消します。
tombstone_delete_class_still_in_code deleted tombstone が、まだコードでエクスポートされているクラスを指名しています。 先にコードからクラスを削除し、そのあとで tombstone をデプロイします。
tombstone_delete_blocked_by_external_bindings アカウント内の別の Worker が、削除対象の名前空間へバインドしています。 参照側 Worker からバインディングを外して再デプロイし、そのあとで自分のデプロイを再実行します。
tombstone_renamed_to_occupied renamed_to の対象が、その名前の既存名前空間と衝突しています。 先のデプロイで、衝突している名前空間自身の deleted tombstone により削除します。
transferred_pending_not_found transferred tombstone に対応する expecting-transfer エントリが、ターゲットにありません。 先にターゲット Worker を、この Worker を指名する expecting-transfer エントリ付きでデプロイします。
transferred_target_missing transferred_to が指名するターゲット Worker が、もう存在しません。 transferred_to を有効なターゲットへ更新するか、tombstone を削除します。
transferred_target_mismatch transferred_to の値が、保留中の転送に記録されたターゲットと一致しません。 transferred_to を保留中転送のターゲットに合わせるか、ターゲット側で expecting-transfer エントリをキャンセルしてから付け替えます。
transferred_source_in_dispatch_namespace transferred tombstone を宣言しているソース Worker が dispatch namespace 内にあり、dispatch をまたぐ転送はサポートされません。 1 つの dispatch-namespace コンテキスト内で転送します。
transferred_target_in_dispatch_namespace transferred tombstone のターゲットが dispatch namespace 内にあり、dispatch をまたぐ転送はサポートされません。 ターゲットが expecting-transfer なしで再デプロイして保留中転送をキャンセルするか、両方の Worker を同じコンテキストに置きます。
phase_one_transfer_after_commit_mismatch ターゲットの名前空間が、宣言とは別のソースから転送されています。 expecting-transfer エントリを削除します。確定後に転送先を付け替えることはできません。
phase_one_transfer_target_class_provisioned ターゲット Worker が、すでにそのクラスの名前空間を持っています。 expecting-transfer エントリを通常のライブエントリに置き換えるか、先に既存の名前空間を削除します。
phase_one_transfer_duplicate 同じクラス向けに、別の expecting-transfer ヒントがすでに進行中です。 先に既存の保留中転送を、エントリの削除または置き換えでキャンセルします。
phase_one_transfer_source_missing transfer_from が指名するソース Worker が、アカウントに存在しません。 ソース Worker の名前を直します。
phase_one_transfer_source_namespace_missing ソース Worker に、そのクラスの名前空間がありません。 ターゲットが expecting-transfer を宣言する前に、ソース Worker へクラスをデプロイしておきます。
phase_one_transfer_source_in_dispatch_namespace ソース Worker が dispatch namespace 内にあり、dispatch をまたぐ転送はサポートされません。 転送を 1 つの dispatch-namespace コンテキスト内へ移します。
phase_one_transfer_target_in_dispatch_namespace ターゲット Worker が dispatch namespace 内にあり、dispatch をまたぐ転送はサポートされません。 転送を 1 つの dispatch-namespace コンテキスト内へ移します。
storage_type_mismatch 宣言した storage の値が、プロビジョニング済み名前空間のストレージバックエンドと一致しません。 ストレージバックエンドは、その場では変更できません。本当に切り替える必要がある場合は、名前空間を削除し、新しいバックエンドで再プロビジョニングします。
free_tier_requires_sqlite アカウントのプランは SQLite バックエンドの名前空間だけに対応していますが、エントリが legacy-kv を要求しています。 "storage": "sqlite" を使います。

制約と制限

  • exportsmigrations は同時に使えません。 両方のフィールドを含む Worker 設定は、検証時に拒否されます。一度 exports でデプロイした Worker は、以降のデプロイでも exports を使い続ける必要があります(どちらも使わない場合は空の設定と照合され、通常は誤りです)。
  • wrangler versions upload はライフサイクル変更を適用しません。 従来の migrations 配列と同じく、Durable Object のライフサイクル変更は wrangler deploy 経由でのみ適用できます。Wrangler 設定に exports エントリがある場合、wrangler versions upload は対処可能なエラーですぐ失敗します。デプロイ管理 - Durable Object のマイグレーション を参照してください。
  • 段階的デプロイは exports では使えません。 ライフサイクル変更は Cloudflare コントロールプレーンでアトミックであり、段階的にはロールアウトできません。Durable Objects での段階的デプロイ - Durable Object クラスのライフサイクル変更 を参照してください。
  • ロールバックはライフサイクル変更をまたげません。 exports によるライフサイクル変更より前にデプロイしたバージョンへは、ロールバックできません。ロールバック - バインディング を参照してください。
  • ストレージバックエンドは、プロビジョニング後は変更できません。 名前空間の storage の値をその場で変えることはできません。削除して再プロビジョニングします。

従来の migrations フローから移行する

migrations 配列 を使っている既存の Workers は、データの移行なしで exports へ移れます。プロビジョニング済み名前空間はそのまま残り、変わるのは設定の形だけです。

クラスの既存ストレージバックエンドを知るには、最初に作成したマイグレーションまでたどります。new_sqlite_classes で導入したクラスは sqlitenew_classes で導入したクラスは legacy-kv です。

  1. いま Worker がエクスポートしている、ライブの Durable Object クラスを特定します。アクティブな名前空間を持つ各クラスが、ライブの exports エントリになります。
  2. migrations 配列を exports マップに置き換えます。既存の各クラスについて、クラス名をキーにしたエントリを追加し、"type": "durable-object" を設定します。既存のストレージバックエンドに合わせて "storage": "sqlite" または "storage": "legacy-kv" を指定します。
  3. 設定から migrations 配列を削除します。
  4. デプロイします。

典型的な migrations 履歴と等価な内容を並べると、次のとおりです。

{
	"migrations": [
		{ "tag": "v1", "new_sqlite_classes": ["ChatRoom"] }
	]
}
[[migrations]]
tag = "v1"
new_sqlite_classes = [ "ChatRoom" ]
{
	"exports": {
		"ChatRoom": { "type": "durable-object", "storage": "sqlite" }
	}
}
[exports.ChatRoom]
type = "durable-object"
storage = "sqlite"

以降のライフサイクル変更(削除、名前変更、転送)は、すべて exports 経由で行います。tag フィールドに相当するものはなく、履歴エントリを残す必要もありません。いまの exports マップの状態が、信頼できる情報源です。

役に立ちましたか?