# バッチ設計書 88-Packages::Debian::CleanupDanglingPackageFilesWorker

## 概要

本ドキュメントは、Debianパッケージの宙ぶらりんファイルをクリーンアップするバッチ処理「Packages::Debian::CleanupDanglingPackageFilesWorker」の設計仕様を定義するものである。

### 本バッチの処理概要

このバッチは、Debianパッケージレジストリ内で「unknown」状態のまま3時間以上経過したパッケージファイルを検出し、削除対象としてマークするCronジョブである。

**業務上の目的・背景**：Debianパッケージのアップロード処理は複数のステップで構成されており、中間状態（unknown）のファイルが一時的に作成される。アップロードが中断された場合や処理が失敗した場合、これらのファイルが宙ぶらりん（dangling）状態で残ることがある。このバッチは、3時間以上unknown状態のファイルを検出し、削除対象としてマークすることで、ストレージの無駄な使用を防止する。

**バッチの実行タイミング**：Cronジョブとして定期的に実行される。処理のタイムアウトは250秒に設定されている。

**主要な処理内容**：
1. debian_packagesフィーチャーフラグが有効か確認
2. 3時間以上前にunknown状態となったinstallableなパッケージファイルを取得
3. MarkPackageFilesForDestructionServiceを使用して削除対象としてマーク
4. エラー発生時はGitlab::ErrorTrackingでログ記録

**前後の処理との関連**：CleanupPackageRegistryWorker（No.86）でエンキューされるCleanupPackageFileWorkerが実際の削除を行う。本バッチは削除対象のマーキングのみを行う。

**影響範囲**：packages_package_filesテーブル（Debianパッケージ用）。

## バッチ種別

データクレンジング（マーキング処理）

## 実行スケジュール

| 項目 | 内容 |
|-----|------|
| 実行頻度 | 定期実行（Cron） |
| 実行時刻 | 設定により異なる |
| 実行曜日 | 毎日 |
| 実行日 | 毎日 |
| トリガー | cron |

## 実行条件

### 前提条件

| 条件 | 説明 |
|-----|------|
| feature_flag | debian_packagesフィーチャーフラグが有効であること |
| feature_category | package_registry機能が有効であること |

### 実行可否判定

debian_packagesフィーチャーフラグが無効の場合は即座に終了する。

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | デフォルト値 | 説明 |
|-------------|-----|-----|-------------|------|
| なし | - | - | - | パラメータなしで実行 |

### 入力データソース

| データソース | 形式 | 説明 |
|-------------|------|------|
| Packages::PackageFile | DB | Debianパッケージファイル |

## 出力仕様

### 出力データ

| 出力先 | 形式 | 説明 |
|-------|------|------|
| packages_package_files | DB | ステータスをpending_destructionに更新 |

### 出力ファイル仕様

ファイル出力なし。

## 処理フロー

### 処理シーケンス

```
1. ワーカー起動
   └─ Sidekiqによりジョブがキューから取得される
2. フィーチャーフラグ確認
   ├─ debian_packages無効の場合：即座に終了
   └─ 有効の場合：処理継続
3. 対象ファイル取得
   └─ with_debian_unknown_since(3時間前).installableでクエリ
4. 削除マーキング
   └─ MarkPackageFilesForDestructionService実行
5. エラーハンドリング
   └─ StandardError発生時はErrorTrackingでログ記録
```

### フローチャート

```mermaid
flowchart TD
    A[バッチ開始] --> B{debian_packages有効?}
    B -->|No| C[バッチ終了]
    B -->|Yes| D[対象ファイル取得]
    D --> E[with_debian_unknown_since 3時間]
    E --> F[installableスコープ適用]
    F --> G[MarkPackageFilesForDestructionService実行]
    G --> H{エラー発生?}
    H -->|Yes| I[ErrorTracking.log_exception]
    H -->|No| C
    I --> C
```

## データベース操作仕様

### 操作別データベース影響一覧

| 処理 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| 対象ファイル取得 | packages_package_files | SELECT | unknown状態のDebianファイルを取得 |
| ステータス更新 | packages_package_files | UPDATE | pending_destructionにマーク |

### テーブル別操作詳細

#### packages_package_files

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| SELECT | * | file_type = 'unknown', updated_at < 3時間前, status = 'installable' | with_debian_unknown_sinceスコープ |
| UPDATE | status | pending_destruction | サービス経由で更新 |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | StandardError | 処理中の例外 | ErrorTrackingでログ記録、次回実行を待つ |
| - | DBエラー | データベース接続失敗 | 自動リトライ |

### リトライ仕様

| 項目 | 内容 |
|-----|------|
| リトライ回数 | Sidekiqデフォルト |
| リトライ間隔 | Sidekiqデフォルト（指数バックオフ） |
| リトライ対象エラー | 一般的な例外 |

### 障害時対応

idempotent!が設定されているため、再実行しても安全。エラーはGitlab::ErrorTrackingで記録される。

## トランザクション仕様

| 項目 | 内容 |
|-----|------|
| トランザクション範囲 | サービス内部で管理 |
| コミットタイミング | サービス内部で管理 |
| ロールバック条件 | サービス内部で管理 |

## パフォーマンス要件

| 項目 | 内容 |
|-----|------|
| 想定処理件数 | 可変（宙ぶらりんファイル数に依存） |
| 目標処理時間 | 最大250秒（BATCH_TIMEOUT） |
| メモリ使用量上限 | サービス内部で制御 |

## 排他制御

deduplicate :until_executedが設定されており、同一ジョブが実行完了まで重複実行されることを防止する。

## ログ出力

| ログ種別 | 出力タイミング | 出力内容 |
|---------|--------------|---------|
| エラーログ | 例外発生時 | Gitlab::ErrorTracking.log_exception |

## 監視・アラート

| 監視項目 | 閾値 | アラート先 |
|---------|-----|----------|
| 処理時間 | 250秒（BATCH_TIMEOUT） | 運用チーム |
| エラー発生 | 1回以上 | 運用チーム |

## 備考

- feature_category: :package_registry
- data_consistency: :sticky
- idempotent: true
- deduplicate: :until_executed
- THREE_HOUR: 3時間（unknown状態の閾値）
- BATCH_TIMEOUT: 250秒
- Feature.enabled?(:debian_packages)で実行可否を判定
- MarkPackageFilesForDestructionServiceのbatch_deadline引数で処理時間を制限
