active: true
derived: false
groups:
- LIFE
header: |
  ストレージメンテナンスのための確率的自動エビクション
level: 1.37
links:
- ARCH007: CwMzyqNroQBWBsDCle5fnJuThTmWAJnkFAcL_z2OzCs=
- REQ007: FAk1im9qkBhtzNEPuqhcaOz9Xmme-nmrkiZc7bGQDNk=
normative: true
ref: ''
reviewed: nl5wmpi7EVZvY_nW0uvTSm3tFs94xQUPy5duolRDMy0=
status: accepted
text: |
  # ストレージメンテナンスのための確率的自動エビクション

  ## コンテキストと課題

  `beautyspot` はキャッシュの TTL をサポートしており、期限切れデータは論理的に無効化されます。しかし、ユーザーが明示的にクリーンアップを呼び出さない限り、有効期限切れのメタデータや巨大な孤立 Blob ファイルは物理的に削除されず、ストレージが肥大化し続けるという問題がありました。

  ユーザーにインフラ管理を意識させない「黒子」としての哲学を維持しつつ、自動でガベージコレクション（エビクション）を行う仕組みが必要になりました。

  ## 判断基準

  * **Autonomy**: ユーザーが手動でメンテナンススクリプトを書くことなく、ストレージの肥大化が自動的に抑制されること。
  * **Zero Latency Impact**: エビクション処理がアプリケーションのメインロジックの応答速度（レイテンシ）を低下させないこと。
  * **Simplicity**: 複雑な容量計算や頻繁な DB 更新を避け、実装と保守のコストを最小限に抑えること。

  ## 検討した選択肢

  1.  **Capacity-based LRU (Least Recently Used) Policy:**
      * ストレージ容量やレコード数の上限に達した際に古いデータを削除する。
      * **評価:** 却下。キャッシュヒットのたびにタイムスタンプを更新する必要があり、DB の書き込み競合やレイテンシ低下を招く。
  2.  **Load-Adaptive Background Eviction:**
      * アイドル状態のときにのみクリーンアップタスクを投入する。
      * **評価:** 却下。実装が複雑になりすぎる（オーバーエンジニアリング）。
  3.  **Probabilistic Auto-Eviction (確率的自動実行):**
      * 新しい結果の保存直後、設定された確率に基づいてバックグラウンドでクリーンアップタスクを投入する。
      * **評価:** **採用。** シンプルかつ低コスト。

  ## 決定事項

  採用した選択肢: **Option 3**.

  **確率的自動エビクション**を採用します。

  * `Spot` の初期化パラメータに `eviction_rate: float = 0.0` を追加し、オプトイン方式とします。
  * エビクション処理は、メインスレッドやイベントループをブロックしないよう、`_BackgroundLoop` にオフロードします。
  * ロック競合を防ぐため、掃除タスクの内部に非ブロッキングロックを導入し、重複実行を安全にスキップさせます。

  ## 影響・結果

  * **ポジティブ**:
      * ユーザーは設定一つで、メインロジックの性能を犠牲にすることなくストレージの肥大化を防げる。
      * 実装がシンプルで保守コストが低い。
  * **ネガティブ**:
      * 確率に依存するため、決定論的な容量解放の保証はない。厳密な管理が必要な場合は引き続き手動での呼び出しが必要。
