# バッチ設計書 76-Environments::AutoDeleteCronWorker

## 概要

本ドキュメントは、期限切れ環境を自動削除するバッチ `Environments::AutoDeleteCronWorker` の設計仕様を記載する。

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

このバッチは、自動削除時刻（auto_delete_at）が過ぎた停止済み環境（Environment）を検出し、削除処理を実行するワーカーである。

**業務上の目的・背景**：GitLabのCI/CD機能で作成された環境は、使用されなくなった後も停止状態でデータベースに残存する。これらの環境レコードが蓄積されると、データベースの肥大化やUIのパフォーマンス低下につながる。自動削除機能により、停止済みで一定期間経過した環境を自動的に削除することで、データベースのサイズを最適化し、システム全体のパフォーマンスを維持する。`AutoStopCronWorker` で停止された環境がその後このワーカーで削除される流れとなる。

**バッチの実行タイミング**：毎時34分（`34 * * * *`）にCronジョブとして実行される。

**主要な処理内容**：
1. ループ処理を開始（タイムアウト45分、最大1000回）
2. 自動削除対象の環境を100件ずつバッチ取得
3. 各環境に対して `destroy` を実行
4. 対象がなくなるか、制限に達するまで継続

**前後の処理との関連**：`Environments::AutoStopCronWorker` で環境が停止された後、このワーカーが一定期間後に環境を削除する。

**影響範囲**：`environments` テーブルからのレコード削除、関連するデプロイメント情報

## バッチ種別

データクレンジング / 自動削除処理

## 実行スケジュール

| 項目 | 内容 |
|-----|------|
| 実行頻度 | 毎時 |
| 実行時刻 | 毎時34分 |
| 実行曜日 | 全曜日 |
| 実行日 | 毎日 |
| トリガー | cron（`34 * * * *`） |

## 実行条件

### 前提条件

| 条件 | 説明 |
|-----|------|
| データベース接続 | 読み書き可能な接続 |

### 実行可否判定

- 自動削除対象の環境が存在しない場合はループ終了
- タイムアウトまたはループ上限に達した場合は処理終了

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | デフォルト値 | 説明 |
|-------------|-----|-----|-------------|------|
| なし | - | - | - | このワーカーはパラメータを受け取らない |

### 入力データソース

| データソース | 形式 | 説明 |
|-------------|------|------|
| environments | DB | 自動削除対象の環境レコード |

## 出力仕様

### 出力データ

| 出力先 | 形式 | 説明 |
|-------|------|------|
| environments | DB | レコード削除 |

### 出力ファイル仕様

ファイル出力なし

## 処理フロー

### 処理シーケンス

```
1. ループ処理開始
   └─ タイムアウト: 45分
   └─ 最大ループ回数: 1000回
2. バッチ取得（100件）
   └─ Environment.auto_deletable(100)
   └─ stopped状態かつauto_delete_at < 現在時刻
3. 削除処理
   └─ 各環境に対して destroy を実行
4. ループ継続判定
   └─ 対象がなくなるか、タイムアウト/回数上限まで継続
```

### フローチャート

```mermaid
flowchart TD
    A[バッチ開始] --> B[ループ開始]
    B --> C[環境取得 100件]
    C --> D{環境あり?}
    D -->|No| E[処理終了]
    D -->|Yes| F[各環境をdestroy]
    F --> G{タイムアウト or 上限?}
    G -->|No| B
    G -->|Yes| E
```

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

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

| 処理 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| auto_deletable | environments | SELECT | 自動削除対象環境の取得 |
| destroy | environments | DELETE | 環境レコードの削除 |
| destroy | 関連テーブル | DELETE | 関連レコードのカスケード削除 |

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

#### environments

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| SELECT | id | state = stopped AND auto_delete_at < NOW() | LIMIT 100 |
| DELETE | - | id = (取得した環境ID) | destroy実行 |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | 削除エラー | 環境削除失敗時 | 例外発生、次の環境に継続 |
| - | データベースエラー | DB接続失敗時 | Sidekiqによる自動リトライ |

### リトライ仕様

| 項目 | 内容 |
|-----|------|
| リトライ回数 | Sidekiqデフォルト |
| リトライ間隔 | Sidekiqデフォルト |
| リトライ対象エラー | 標準例外 |

### 障害時対応

- 削除失敗時は次回の毎時実行で再試行
- 個々の環境削除失敗はログに記録され、処理は継続

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

| 項目 | 内容 |
|-----|------|
| トランザクション範囲 | 各 destroy ごと（Rails標準） |
| コミットタイミング | 各レコード削除完了時 |
| ロールバック条件 | 個別レコード削除失敗時 |

## パフォーマンス要件

| 項目 | 内容 |
|-----|------|
| 想定処理件数 | バッチサイズ100件 × 最大1000ループ |
| 目標処理時間 | 45分以内 |
| メモリ使用量上限 | バッチサイズで制御 |

## 排他制御

- `deduplicate :until_executed, including_scheduled: true` で重複実行を防止
- `Gitlab::LoopHelpers` によるループ制御（タイムアウト45分、最大1000回）

## ログ出力

| ログ種別 | 出力タイミング | 出力内容 |
|---------|--------------|---------|
| 開始ログ | ジョブ開始時 | ジョブID、クラス名 |
| 終了ログ | ジョブ完了時 | 処理結果 |
| エラーログ | エラー発生時 | 例外情報 |

## 監視・アラート

| 監視項目 | 閾値 | アラート先 |
|---------|-----|----------|
| ジョブ失敗率 | 継続的な失敗 | Sidekiq監視システム |
| 処理時間 | 45分超過 | 管理者通知 |

## 備考

- このワーカーは `idempotent!` として宣言されている
- feature_category は `continuous_delivery`
- data_consistency は `always` に設定
- `deduplicate :until_executed, including_scheduled: true` で重複排除
- 毎時34分の実行で、`AutoStopCronWorker`（毎時24分）の10分後に実行
- 停止済み環境のみが削除対象（available状態の環境は対象外）
- 各環境は個別に `destroy` が呼ばれ、Railsのコールバックが実行される
