# バッチ設計書 103-Releases::PublishEventWorker

## 概要

本ドキュメントは、リリース公開イベントを発行するバッチ処理「Releases::PublishEventWorker」の設計内容を記載する。

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

**業務上の目的・背景**：GitLabのリリース機能において、リリースが公開されたタイミングで外部システムやGitLab内部の他の機能に通知する必要がある。本バッチは、公開待ちのリリースに対してReleasePublishedEventを発行することで、Webhookやその他の連携機能がリリース公開を検知し、適切なアクションを実行できるようにすることを目的としている。

**バッチの実行タイミング**：Cronジョブとして定期的に実行される。リリース時刻から前後1時間以内かつ未公開のリリースを対象とする。

**主要な処理内容**：
1. 公開イベント未発行かつリリース時刻が範囲内のリリースを検索（最大5000件）
2. 100件ずつバッチ処理で各リリースを処理
3. 各リリースに対してProjects::ReleasePublishedEventをEventStoreに発行
4. 処理済みリリースのrelease_published_atカラムを更新
5. 公開したリリース数をメタデータとして記録

**前後の処理との関連**：本バッチが発行するイベントは、Gitlab::EventStoreを通じて各種イベントハンドラーに配信される。Webhook、インテグレーション、通知機能などがこのイベントを購読している。

**影響範囲**：releasesテーブル（release_published_atカラム）、EventStore、Webhook、外部連携システムに影響する。

## バッチ種別

イベント発行 / 通知配信

## 実行スケジュール

| 項目 | 内容 |
|-----|------|
| 実行頻度 | 定期実行（Cronjob） |
| 実行時刻 | システム設定による |
| 実行曜日 | 毎日 |
| 実行日 | 該当なし |
| トリガー | cron |

## 実行条件

### 前提条件

| 条件 | 説明 |
|-----|------|
| リリースの存在 | 公開イベント未発行のリリースが存在すること |
| リリース時刻 | released_at が現在時刻の前後1時間以内であること |
| リリース機能有効 | プロジェクトでリリース機能が有効であること |

### 実行可否判定

- release_published_at が NULL（unpublished）かつリリース時刻が範囲内（released_within_2hrs）のリリースが対象
- プロジェクトでリリース機能が有効（with_feature_enabled(:releases)）であること
- 最大5000件まで処理

## 入力仕様

### 入力パラメータ

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

### 入力データソース

| データソース | 形式 | 説明 |
|-------------|------|------|
| releases | DB | 公開イベント未発行のリリース情報 |
| projects | DB | プロジェクト情報（リリース機能の有効確認） |
| project_features | DB | プロジェクト機能設定 |

## 出力仕様

### 出力データ

| 出力先 | 形式 | 説明 |
|-------|------|------|
| releases.release_published_at | DB | 公開処理完了時刻を記録 |
| EventStore | イベント | Projects::ReleasePublishedEventを発行 |

### 出力ファイル仕様

該当なし

## 処理フロー

### 処理シーケンス

```
1. 対象リリース取得
   └─ Release.waiting_for_publish_event で対象リリースを取得（最大5000件）
2. バッチ処理開始
   └─ each_batch(of: 100) で100件ずつ処理
3. 各リリースの処理
   └─ with_context(project:) でコンテキスト設定
4. イベント発行
   └─ EventStore.publish(ReleasePublishedEvent)
5. 公開カウント増加
   └─ releases_published += 1
6. 公開日時更新
   └─ releases.touch_all(:release_published_at)
7. メタデータ記録
   └─ log_extra_metadata_on_done(:releases_published, count)
```

### フローチャート

```mermaid
flowchart TD
    A[バッチ開始] --> B[公開待ちリリース取得]
    B --> C{リリースあり?}
    C -->|なし| H[バッチ終了]
    C -->|あり| D[100件ずつバッチ処理]
    D --> E[各リリースにイベント発行]
    E --> F[release_published_atを更新]
    F --> G{次のバッチ?}
    G -->|あり| D
    G -->|なし| I[公開件数をログ出力]
    I --> H
```

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

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

| 処理 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| リリース取得 | releases | SELECT | 公開イベント未発行のリリースを取得 |
| プロジェクト確認 | projects, project_features | SELECT（JOIN） | リリース機能の有効確認 |
| 公開日時更新 | releases | UPDATE | release_published_atを現在時刻で更新 |

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

#### releases

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| SELECT | id, project_id, released_at, release_published_at | release_published_at IS NULL AND released_at BETWEEN (now - 1h) AND (now + 1h) | |
| UPDATE | release_published_at | 現在時刻（touch_all） | バッチ単位で一括更新 |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | StandardError | イベント発行エラー | Sidekiqの標準リトライで対処 |

### リトライ仕様

| 項目 | 内容 |
|-----|------|
| リトライ回数 | Sidekiq標準（25回） |
| リトライ間隔 | 指数バックオフ |
| リトライ対象エラー | すべての例外 |

### 障害時対応

冪等性（idempotent!）が宣言されているため、リトライしても問題ない。touch_allによる更新は再実行時に影響なし。

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

| 項目 | 内容 |
|-----|------|
| トランザクション範囲 | バッチ単位（100件） |
| コミットタイミング | touch_all実行時 |
| ロールバック条件 | バッチ処理中のエラー発生時 |

## パフォーマンス要件

| 項目 | 内容 |
|-----|------|
| 想定処理件数 | 最大5000件/実行 |
| 目標処理時間 | 数秒〜数十秒（対象件数に依存） |
| メモリ使用量上限 | 特に制限なし（バッチ処理で制御） |

## 排他制御

特に排他制御は実装されていない。冪等性が保証されているため、同時実行されても問題ない。

## ログ出力

| ログ種別 | 出力タイミング | 出力内容 |
|---------|--------------|---------|
| 開始ログ | バッチ開始時 | Sidekiq標準ログ |
| 終了ログ | バッチ終了時 | Sidekiq標準ログ |
| メタデータ | 処理完了時 | releases_published: 公開したリリース数 |

## 監視・アラート

| 監視項目 | 閾値 | アラート先 |
|---------|-----|----------|
| 実行状況 | Sidekiq標準監視 | 運用チーム |
| 公開リリース数 | メタデータログ | 運用チーム |

## 備考

- feature_category: release_orchestration
- data_consistency: always
- idempotent!: 冪等ワーカー
- MAX_NUMBER_TO_PUBLISH: 5000（1回の実行で処理する最大リリース数）
- EventStoreを通じてProjects::ReleasePublishedEventが各種ハンドラーに配信される
- with_contextでプロジェクトコンテキストを設定してイベント発行
