Skip to content

feat(worker): time-based retention sweep for unprocessed events via DO alarm#237

Merged
liplus-lin-lay merged 1 commit into
mainfrom
236-unprocessed-retention-alarm-sweep
Jun 25, 2026
Merged

feat(worker): time-based retention sweep for unprocessed events via DO alarm#237
liplus-lin-lay merged 1 commit into
mainfrom
236-unprocessed-retention-alarm-sweep

Conversation

@liplus-lin-lay

Copy link
Copy Markdown
Member

概要

未処理 webhook イベントの保持上限を導入し, DO ストレージ肥大の唯一残った無限増加経路を塞ぐ. あわせて retention 仕様 (処理済み 7 日 / 未処理 90 日 / Alarms sweep) をユーザー向け README 二枚に明記する.

Closes #236

背景

変更内容

  • 時間駆動 sweep (DO Alarm): WebhookStore DO に ctx.storage.setAlarm + alarm() ハンドラを追加. sweep は処理済み (>PURGE_AFTER_DAYS, 既定 7 日) と未処理 (>UNPROCESSED_PURGE_AFTER_DAYS, 既定 90 日) の両方をまとめて削除する. alarm() は実行後に次回 sweep を再スケジュールし, mark_processed を一度も呼ばない放置テナントでも消費ゼロで日次実行される. これが本質的な保証.
  • mark_processed 即時 purge は維持: 即時性のための補助経路として残した (処理済みのみ).
  • 新規 env: UNPROCESSED_PURGE_AFTER_DAYS (既定 90) を worker/wrangler.toml [vars] に追加. 未処理を処理済みより長く取るのは未読データ消失の安全域 (7 日 / 90 日の非対称は意図的).
  • docs: docs/0-requirements.md / .ja.md に F2.5 (Alarm sweep) と N2.8 (未処理保持期間) を追記.
  • README 二枚: root README.mdmcp-server/README.md (NPM 公開パッケージ) に retention 仕様を明記 (処理済み 7 日 / 未処理 90 日 / Alarms sweep / env 可変). local-mcp/ は private のため対象外.

既知の限界 (スコープ外)

時間窓は「古さ」を縛るが「量」は縛らない. 高頻度 × 無消費テナントは 90 日窓があっても 1GB 壁に先に到達しうる. 量ベースの hard cap は別 issue 候補.

設計判断: DO Alarms を採用 (フォールバック不要)

issue は DO Alarms が現プランで制約/不可の場合に mark_processed トリガへフォールバックする path を残していたが, テスト環境 (@cloudflare/vitest-pool-workers / miniflare) が setAlarm / getAlarm / alarm() および runDurableObjectAlarm / runInDurableObject テストヘルパを完全サポートすることを確認したため, DO Alarms をそのまま採用した (フォールバック不採用).

テスト

worker/test/workers/store.test.ts に 7 件追加:

  • 未処理 >90 日が sweep で削除される
  • 未処理 <90 日 (89 日) は残る
  • 処理済み >7 日が sweep で削除される (mark_processed 呼び出しなし)
  • 処理済み (>7 日) と未処理 (>90 日) を混在 sweep し, 期限内の両クラスは残す
  • sweep が overdue 件数を正しく報告する
  • 初回 fetch で alarm が arm され, alarm 発火後に再スケジュールされる
  • alarm() が放置テナントの overdue 未処理行を掃除する

全テスト green (worker pool 35 件 + tsx node 54 件).

… events

未処理イベントの保持上限を導入し, DO ストレージ肥大の唯一残った無限増加経路を塞ぐ.

WebhookStore DO に時間駆動の retention sweep を追加する. sweep は処理済み
(>PURGE_AFTER_DAYS, 既定 7 日) と未処理 (>UNPROCESSED_PURGE_AFTER_DAYS, 既定
90 日) の両方をまとめて削除する. トリガは DO Alarm (ctx.storage.setAlarm +
alarm() ハンドラ) で, alarm() は実行後に次回 sweep を再スケジュールするため,
mark_processed を一度も呼ばない放置テナントでも消費ゼロで日次実行される.
既存の mark_processed 即時 purge は即時性のため残した.

未処理保持期間を処理済みより長く取るのは未読データ消失の安全域確保のため
(7 日 / 90 日の非対称は意図的). 新規 env UNPROCESSED_PURGE_AFTER_DAYS を
wrangler.toml [vars] に追加した. docs/0-requirements (.ja 含む) に F2.5 と
N2.8 を追記し, root README と mcp-server/README に retention 仕様を明記した.

テストは未処理 >90 日削除 / <90 日残存 / 処理済み >7 日削除 / 混在 sweep /
alarm 再スケジュール / 放置テナント alarm 掃除 を検証する.

Closes #236
@cloudflare-workers-and-pages

Copy link
Copy Markdown

Deploying with  Cloudflare Workers  Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

Status Name Latest Commit Updated (UTC)
✅ Deployment successful!
View logs
github-webhook-mcp 1beae2b Jun 25 2026, 05:31 PM

@liplus-lin-lay liplus-lin-lay self-assigned this Jun 25, 2026

@liplus-lin-lay liplus-lin-lay left a comment

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AI セルフレビュー (auto mode / 親)

差分確認、完了条件すべて達成。

  • sweep(): processed>7d + unprocessed>90d をまとめて DELETE し件数返却。resolveDays で env 解決を DRY 化 (未設定/非数値/負値 -> 既定、0=即時)。
  • Alarm: ensureAlarm が未設定時のみ arm (getAlarm()===null)、alarm() が sweep 後に自己再スケジュール -> 消費ゼロでも日次周期。fetch 経路で arm。
  • 消費非依存の保証をテストで実証: 放置テナント (200d 未処理) が mark_processed 無しで alarm() により削除 / alarm の arm+fire+re-arm / 境界 (89d 残 / 90d+ 削除) / mixed。runInDurableObject + runDurableObjectAlarm の正規ヘルパ使用。
  • /sweep は内部テスト seam (DO は Worker 経由のみ到達、外部非露出)。
  • docs F2.4/F2.5/N2.7/N2.8 (.ja 含む)、README 2 枚 (root + mcp-server、env は Worker 側と明記)、local-mcp 非対象 -- 全て整合。
  • scope: quota / 量 hard cap は意図的に対象外 (既知の限界として docs/README に明記)。
  • agent.ts の既存型エラーは本 PR 非対象 (変更 7 ファイルに含まれず main 由来)。
  • PR/commit title ASCII、CI 全 green。

判定: PASS。auto mode につき squash merge。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat(worker): unprocessed-event retention via DO alarm sweep + document retention in READMEs

1 participant