Workers 固有の制約
upstream Misskey は常駐する Node.js プロセスを前提に設計されています。Cloudflare Workers ではその前提が成り立たないため、以下の制約に合わせて設計を変えています。
実行モデル
| 制約 | 影響 | 対応 |
|---|---|---|
| 常駐プロセスがなく、実行環境(isolate)は多数並び、いつ破棄されるか分からない | メモリ上の状態を共有・保持できない | 共有が必要な状態は Durable Objects、KV、PostgreSQL に置く |
| プロセス間の pub/sub がない | キャッシュの即時無効化ができない | 変更頻度の低いデータ(meta、ロールなど)は短い有効期限で保持する。ほかの実行環境への反映は最大 30 秒遅れる |
| メモリ上で差分を積み上げて定期的に書き出す方式が使えない | upstream のチャート記録方式が使えない | チャートは元のデータから都度集計する。ID に作成時刻が含まれるため追加の記録は不要。削除数とイベント由来の系列は記録できない |
| 1 回の実行の CPU 時間・サブリクエスト数に上限がある | 大きなジョブを 1 回で処理できない | アカウント削除・インポート・アカウント移行などはジョブを小さなステップに分割し、続きを Queue に再投入する |
| メモリは 128 MB | 大きなファイルや出力を一度に扱えない | アップロード上限を既定 100 MB とする。エクスポートは極端に大きいアカウントで上限に達し得る |
| マシン情報(CPU・メモリ・ディスク)を取得できない | サーバー情報を返せない | 形式は upstream と同じで値は固定 |
非同期処理
| 制約 | 影響 | 対応 |
|---|---|---|
| Queues の遅延は最大 12 時間 | 長い遅延ジョブを 1 回で予約できない | 予約投稿と投票の締め切りは Durable Object のアラームで実行する。24 時間後の処理(アカウント移行)は複数回に分けて待つ |
| Worker から Queues のメッセージ一覧を取得・削除できない | upstream のジョブ管理画面を再現できない | 失敗・遅延したジョブを Durable Object に記録し、その範囲で管理画面に表示する。待機中のジョブは表示・削除できない |
ネットワークと外部サービス
| 制約 | 影響 | 対応 |
|---|---|---|
| 接続先の IP アドレスを確認できず、DNS も引けない | 解決後のアドレスで SSRF を判定できない | ホスト名で判定し、リダイレクトのたびに検査する |
| SMTP(TCP)で送信できない | upstream のメール設定が使えない | Cloudflare Email Service で送信する(Workers Paid プランが前提) |
| リクエストボディの上限はゾーンのプランで決まる(Free / Pro は 100 MB) | アップロード上限をプラン以上に上げられない | 既定の上限をプランに合わせる。upstream のクライアントは単一リクエストでアップロードするため、分割アップロードは採らない |
| ネイティブモジュール(sharp、ffmpeg)を Worker で実行できない | 画像・動画の変換ができない | Containers で実行する。Container が止まっていてもアップロードは成功し、サムネイルが作られないだけ |
| 機械学習モデルを載せると Container が大きく重くなる | センシティブ画像の自動判定を行えない | 対応しない(設定値は保存されるが効果はない) |
データベース
| 制約 | 影響 | 対応 |
|---|---|---|
| Workers から PostgreSQL へは Hyperdrive 経由で接続する | 接続コストが高い | 1 リクエストで 1 接続を使い回す。データベースに近い場所で実行する(Smart Placement) |
| Hyperdrive の SELECT キャッシュは書き込みで無効化されない | 書き込み直後に古い値を読む | キャッシュを無効にして運用する |
| Cloudflare D1 は SQLite | 既存の Misskey の DB を引き継げない | 使わない。Durable Object の SQLite は Durable Object 内部の状態にのみ使う |
デプロイ
| 制約 | 影響 | 対応 |
|---|---|---|
| 別の Worker の Durable Object を参照するには、所有する Worker が先にデプロイされている必要がある | デプロイ順に依存関係がある | 参照の向きを一方向に限り、stream → timeline → media → api → gateway の順でデプロイする |
| Worker は既定で workers.dev のサブドメインにも公開される | インスタンスの URL と異なる入口や、gateway を経由しない入口ができる | 公開するのは gateway のカスタムドメインのみとし、ほかの Worker の公開 URL は無効にする |