# バッチ設計書 55-RepositoryCheck::DispatchWorker

## 概要

本ドキュメントは、GitLabにおけるリポジトリ整合性チェックをディスパッチするバッチ処理「RepositoryCheck::DispatchWorker」の設計を定義する。

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

**業務上の目的・背景**：Gitリポジトリは時間の経過とともに破損する可能性がある（ディスク障害、ファイルシステムの問題など）。GitLabでは、`git fsck`コマンドを使用してリポジトリの整合性を定期的にチェックする機能を提供している。本バッチは、各ストレージシャードに対してリポジトリチェックワーカーをディスパッチし、分散環境でのリポジトリ健全性監視を実現する。

**バッチの実行タイミング**：Cronジョブとして定期実行（時間単位）。リポジトリチェック機能が有効な場合のみ実行。

**主要な処理内容**：
1. リポジトリチェック機能の有効化確認
2. 排他ロック（ExclusiveLease）の取得
3. 利用可能な各シャードに対してBatchWorkerをキューイング
4. BatchWorkerが各シャードのプロジェクトを順次チェック

**前後の処理との関連**：本バッチはディスパッチャとして機能し、実際のチェック処理はBatchWorker、SingleRepositoryWorkerが実行する。

**影響範囲**：projectsテーブルのlast_repository_check_at、last_repository_check_failedカラムが更新される。リポジトリ破損検出時は管理者への通知が行われる可能性がある。

## バッチ種別

監視処理 / ヘルスチェックディスパッチャ

## 実行スケジュール

| 項目 | 内容 |
|-----|------|
| 実行頻度 | 時間単位（Cron設定に依存） |
| 実行時刻 | Cron設定に依存 |
| 実行曜日 | 毎日 |
| 実行日 | - |
| トリガー | cron |

## 実行条件

### 前提条件

| 条件 | 説明 |
|-----|------|
| repository_checks_enabled | Gitlab::CurrentSettings.repository_checks_enabledがtrue |
| ExclusiveLease | 排他ロックを取得できること |

### 実行可否判定

`Gitlab::CurrentSettings.repository_checks_enabled`がfalseの場合は即時終了。排他ロックを取得できない場合もスキップ。

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | デフォルト値 | 説明 |
|-------------|-----|-----|-------------|------|
| なし | - | - | - | Cronジョブのため引数なし |

### 入力データソース

| データソース | 形式 | 説明 |
|-------------|------|------|
| application_settings | DB | リポジトリチェック機能の有効/無効 |
| ストレージシャード設定 | Config | 利用可能なシャード一覧 |

## 出力仕様

### 出力データ

| 出力先 | 形式 | 説明 |
|-------|------|------|
| RepositoryCheck::BatchWorkerキュー | Sidekiq | 各シャードのチェックジョブ |

### 出力ファイル仕様

ファイル出力なし

## 処理フロー

### 処理シーケンス

```
1. リポジトリチェック機能の有効化確認
   └─ Gitlab::CurrentSettings.repository_checks_enabled
2. 排他ロックの取得試行
   └─ try_obtain_lease（1時間タイムアウト）
3. 各シャードに対してBatchWorkerをキュー
   └─ each_eligible_shard { BatchWorker.perform_async(shard_name) }
4. 排他ロックの解放
   └─ リース自動解放
```

### フローチャート

```mermaid
flowchart TD
    A[バッチ開始] --> B{repository_checks_enabled?}
    B -->|No| C[バッチ終了]
    B -->|Yes| D[排他ロック取得試行]
    D --> E{ロック取得成功?}
    E -->|No| C
    E -->|Yes| F[利用可能シャード取得]
    F --> G{シャードあり?}
    G -->|No| H[ロック解放]
    G -->|Yes| I[BatchWorker.perform_async]
    I --> J{次のシャードあり?}
    J -->|Yes| I
    J -->|No| H
    H --> C
```

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

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

| 処理 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| 設定取得 | application_settings | SELECT | リポジトリチェック有効化確認 |
| チェック結果更新 | projects | UPDATE | BatchWorker/SingleRepositoryWorker経由 |

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

#### projects（BatchWorker経由）

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| SELECT | id, last_repository_check_at | repository_storage = shard_name | チェック対象プロジェクト |
| UPDATE | last_repository_check_at, last_repository_check_failed | チェック実行日時、結果 | チェック後に更新 |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | リース取得失敗 | 別インスタンスが実行中 | スキップ（次回実行で再試行） |
| - | DB接続エラー | データベース接続失敗 | Sidekiqによるリトライ |

### リトライ仕様

| 項目 | 内容 |
|-----|------|
| リトライ回数 | Sidekiqデフォルト |
| リトライ間隔 | 指数バックオフ |
| リトライ対象エラー | すべての例外 |

### 障害時対応

排他ロックは1時間でタイムアウトするため、障害発生時も次回実行で自動的に再開可能。

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

| 項目 | 内容 |
|-----|------|
| トランザクション範囲 | なし（ディスパッチのみ） |
| コミットタイミング | - |
| ロールバック条件 | - |

## パフォーマンス要件

| 項目 | 内容 |
|-----|------|
| 想定処理件数 | シャード数分のジョブキューイング |
| 目標処理時間 | 数秒（キューイングのみ） |
| メモリ使用量上限 | 低（軽量ディスパッチャ） |

## 排他制御

ExclusiveLeaseGuardによる排他制御：
- リースキー: worker固有
- タイムアウト: LEASE_TIMEOUT = 1時間

## ログ出力

| ログ種別 | 出力タイミング | 出力内容 |
|---------|--------------|---------|
| 開始ログ | バッチ開始時 | 処理開始 |
| 終了ログ | バッチ終了時 | 処理完了 |

## 監視・アラート

| 監視項目 | 閾値 | アラート先 |
|---------|-----|----------|
| エラー件数 | Sidekiq失敗キュー | 運用チーム |

## 備考

- data_consistency: :always を使用
- feature_category: :source_code_management
- EachShardWorkerをinclude（複数シャード対応）
- ExclusiveLeaseGuardをinclude（排他制御）
- BatchWorkerが実際のチェック処理を実行（最大1時間、バッチサイズ10,000）
- SingleRepositoryWorkerが個別プロジェクトの`git fsck`を実行
- チェック対象：
  - 作成から24時間以上経過した未チェックプロジェクト
  - 最終チェックから1ヶ月以上経過したプロジェクト
