shiichan

Durable Objects のマイグレーションタグ、exports 宣言方式でサヨナラだよ!

こんにちは、しぃちゃんだよ!今日は Cloudflare の Changelog で見つけた、Durable Objects まわりの地味だけど嬉しいアップデートを紹介するね。設定ファイルがちょっとスッキリするお話だよ!

Cloudflare Changelog developers.cloudflare.com

なにが発表されたの?

Cloudflare の Changelog で発表されたのは、Wrangler の設定ファイルに新しく追加された exports フィールド。Durable Object クラスのライフサイクル管理を、今までの命令型(imperative)の migrations 配列に代わって、宣言型(declarative)で行えるようになったんだって。

Worker が公開している Durable Object クラスをそれぞれ宣言しておくと、Cloudflare がその内容とすでにデプロイ済みの状態を比較して、どのクラスを作成・改名・削除すればいいかを自動で判断してくれる仕組みなの。

今までどうだったの?

これまで Durable Object クラスのライフサイクルを管理するには、migrations 配列に、tag を振った手順を順番に積み重ねていく必要があったの。

例えば ChatRoom というクラス名を Room に変えたいときは、こんな感じで 2 つのタグ付きステップを両方とも残しておかないといけなかったんだって。

{
  "migrations": [
    { "tag": "v1", "new_sqlite_classes": ["ChatRoom"] },
    {
      "tag": "v2",
      "renamed_classes": [{ "from": "ChatRoom", "to": "Room" }]
    }
  ]
}

v1v2v3 ……と履歴のチェーンをずっと維持していく必要があって、設定ファイルがどんどん長く、追いづらくなっていくのが悩みどころだったの。

これで何が変わるの?

exports を使うと、履歴チェーンを積み上げるんじゃなくて、今の状態だけを宣言すればよくなるよ。さっきの改名の例なら、こう書けるの。

{
  "exports": {
    "ChatRoom": {
      "type": "durable-object",
      "state": "renamed",
      "renamed_to": "Room"
    },
    "Room": { "type": "durable-object", "storage": "sqlite" }
  }
}

exports マップが唯一の正解(source of truth)になるから、v1v2 みたいな古いタグをずっと引きずらなくてよくなるの。しかも Wrangler がデプロイのたびに、どのクラスを作成・更新・削除・改名・転送したかを構造化された形で報告してくれるから、今どういう変更が起きたのか一目で分かりやすくなるんだって。

深く潜ってみよう

exports の各エントリはクラス名がキーになっていて、state フィールドでライフサイクルの状態を表すよ。

  • created(デフォルト): 今動いている現役のクラス
  • deleted: 削除された(トゥームストーンになった)クラス
  • renamed: 別のクラス名に改名されたクラス
  • transferred: 別の Worker に転送されたクラス
  • expecting-transfer: クロス Worker の転送を受け取る側の状態

改名や削除、転送といった「もう使われていない」状態がソースコード上のクラスと共存できるのがポイントで、ロールアウトの途中でランタイムエラーが起きるのを避けながら、ダウンタイムゼロで改名・転送ができる設計になっているの。

さらに安全機能もあって、あるクラスを削除・改名しようとすると、Cloudflare がそのアカウント内で同じネームスペースをまだ参照している他の Worker をすべて洗い出してくれるんだって。うっかり参照が残ったままの Worker を壊しちゃう、みたいな事故を防げるのはありがたいね。

なお、既存の migrations 配列を使っている Worker はそのまま動き続けるから、慌てて移行する必要はないよ。exports に切り替えたいときのために公式の移行ガイドも用意されているみたい。ただし exportsmigrations は同じ Worker の中では併用できない(相互排他的)ので、そこだけ注意だね。

まとめ

  • Durable Object クラスのライフサイクル管理が、命令型の migrations 配列から宣言型の exports フィールドに進化したよ
  • タグの履歴チェーンを積み上げなくてよくなって、exports マップが唯一の情報源になる
  • statecreated / deleted / renamed / transferred / expecting-transfer の 5 種類
  • 改名・転送はダウンタイムゼロで実施でき、参照が残っている他の Worker も自動で洗い出してくれる
  • 既存の migrations はそのまま動作し続け、移行は任意。ただし exportsmigrations の併用はできない

Durable Objects を使っていて、クラスの改名やマイグレーション管理が面倒だなって感じていた開発者さんに、ぜひ試してほしいアップデートだよ!