# 通知設計書 104-Completed

## 概要

本ドキュメントは、KubernetesのJobコントローラーが発行する「Completed」イベント通知の設計を記述する。Jobが正常に完了した際にNormalイベントとして発行される。

### 本通知の処理概要

Jobコントローラーが同期処理においてJobの完了条件（JobComplete）が満たされたことを検出した場合に発行されるNormalイベントである。

**業務上の目的・背景**：Jobの正常完了はワークロード実行の基本的なライフサイクルイベントである。この通知により、運用者やCI/CDパイプラインがJobの完了を検知し、後続処理の開始や成功ログの記録を行うことができる。バッチ処理の監視において重要な通知である。

**通知の送信タイミング**：Jobコントローラーのsync処理内で、`recordJobFinished`関数が呼び出された際に、finishedConditionがJobCompleteである場合に発行される。具体的には`job_controller.go`の1541行目で発行される。

**通知の受信者**：Kubernetes Event APIを通じてJobオブジェクトに関連付けられるため、`kubectl get events`やモニタリングツールを通じてクラスタ管理者やジョブの実行者が受信する。

**通知内容の概要**：「Job completed」というメッセージが含まれ、Jobが正常に完了したことを通知する。

**期待されるアクション**：通常の完了通知であるため、特別なアクションは不要。後続処理がある場合はそれを開始する。ログとして記録し、ジョブの実行履歴を管理する。

## 通知種別

Kubernetes Event（Normal）

## 送信仕様

### 基本情報

| 項目 | 内容 |
|-----|------|
| 送信方式 | 同期（sync処理内で即座に発行） |
| 優先度 | 低（Normal - 正常完了） |
| リトライ | なし（Kubernetes Event APIの内部リトライに依存） |

### 送信先決定ロジック

Jobオブジェクト自体がイベントの対象（InvolvedObject）となる。

## 通知テンプレート

### Kubernetes Eventの場合

| 項目 | 内容 |
|-----|------|
| EventType | Normal |
| Reason | Completed |
| 発行元コンポーネント | job-controller |

### 本文テンプレート

```
Job completed
```

### 添付ファイル

該当なし

## テンプレート変数

| 変数名 | 説明 | データ取得元 | 必須 |
|--------|------|-------------|-----|
| なし | 本イベントは固定メッセージ | - | - |

## 送信トリガー・条件

### トリガー一覧

| トリガー種別 | トリガーイベント | 送信条件 | 説明 |
|------------|----------------|---------|------|
| コントローラー同期 | Jobのsync処理 | finishedCondition.Type == JobComplete | Jobの完了条件が満たされた場合 |

### 送信抑止条件

| 条件 | 説明 |
|-----|------|
| Job未完了 | 完了条件が満たされていない場合 |
| Job失敗 | finishedConditionがJobFailedの場合はCompletedイベントではなく失敗イベントが発行される |

## 処理フロー

### 送信フロー

```mermaid
flowchart TD
    A[Job sync開始] --> B[Pod状態集計]
    B --> C{完了条件判定}
    C -->|complete=true| D[finishedCondition = JobComplete]
    C -->|complete=false| E[通常処理継続]
    D --> F[recordJobFinished呼び出し]
    F --> G{finishedCond.Type == JobComplete?}
    G -->|Yes| H[Completed Event発行]
    G -->|No| I[失敗イベント発行]
    H --> J[メトリクス更新]
```

## データベース参照・更新仕様

### 参照テーブル一覧

| テーブル名 | 用途 | 備考 |
|-----------|------|------|
| Jobオブジェクト | 完了条件の確認 | etcd経由 |
| Podオブジェクト | 成功/失敗Pod数の集計 | informer経由 |

### テーブル別参照項目詳細

#### Jobオブジェクト

| 参照項目（フィールド名） | 用途 | 取得条件 |
|-------------------|------|---------|
| spec.completions | 完了数の判定基準 | sync時 |
| status.succeeded | 成功Pod数 | sync時 |
| status.conditions | 既存条件の確認 | sync時 |

### 更新テーブル一覧

| テーブル名 | 操作 | 概要 |
|-----------|------|------|
| Jobオブジェクト | UPDATE | status.conditions にJobComplete条件追加、completionTime設定 |
| Eventオブジェクト | INSERT | 完了イベントの記録 |

## エラー処理

### エラーケース一覧

| エラー種別 | 発生条件 | 対処方法 |
|----------|---------|---------|
| ステータス更新失敗 | APIサーバー接続エラー | requeueして再試行 |
| Event発行失敗 | APIサーバー接続エラー | EventBroadcasterの内部リトライに依存 |

### リトライ仕様

| 項目 | 内容 |
|-----|------|
| リトライ回数 | Event APIの内部リトライに依存 |
| リトライ間隔 | EventBroadcasterのデフォルト設定 |
| リトライ対象エラー | APIサーバー一時障害 |

## 配信設定

### レート制限

| 項目 | 内容 |
|-----|------|
| 1分あたり上限 | Kubernetes Event APIのレート制限に依存 |
| 1日あたり上限 | 制限なし（Event集約が適用される） |

### 配信時間帯

制限なし。

## セキュリティ考慮事項

本イベントにはJobの名前とNamespaceのみが含まれ、機密情報は含まれない。

## 備考

- Completedイベントの発行前に、succeededがcompletionsを超えている場合は別途TooManySucceededPodsイベントも発行される（1538-1539行目）
- job_finished_totalメトリクスも同時に記録される（1542行目）
- completionTimeはfinishedConditionのLastTransitionTimeから設定される（1529行目）

---

## コードリーディングガイド

本通知を理解するために参照すべきファイルと、推奨する読み解き順序を以下に示す。

### 推奨読解順序

#### Step 1: データ構造を理解する

JobのConditionとCompletionModeの構造を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | types.go | `vendor/k8s.io/api/batch/v1/types.go` | JobConditionType（JobComplete, JobFailed）の定義 |

#### Step 2: エントリーポイントを理解する

Jobコントローラーのsync処理から完了判定までの流れを理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | job_controller.go | `pkg/controller/job/job_controller.go` | syncJob関数内の完了判定（1035-1038行目） |

**主要処理フロー**:
1. **1035行目**: `succeeded >= *job.Spec.Completions && active == 0`で完了判定
2. **1038行目**: `jobCtx.finishedCondition = jm.newSuccessCondition()`で完了条件設定

#### Step 3: recordJobFinished関数を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | job_controller.go | `pkg/controller/job/job_controller.go` | recordJobFinished関数（1534-1548行目）でのイベント発行 |

**主要処理フロー**:
- **1537行目**: `finishedCond.Type == batch.JobComplete`の判定
- **1541行目**: `recorder.Event`で"Completed"イベント発行

### プログラム呼び出し階層図

```
Controller.syncJob
    |
    +-- 完了条件判定 (1035行目)
    |       |
    |       +-- newSuccessCondition (1038行目)
    |
    +-- recordJobFinished (1534行目)
            |
            +-- recorder.Event "Completed" (1541行目)
            +-- metrics.JobFinishedNum.Inc (1542行目)
```

### データフロー図

```
[入力]                          [処理]                              [出力]

Job.spec.completions      --> syncJob
Job.status.succeeded          完了判定                        --> finishedCondition
activePods count          --> succeeded >= completions
                              && active == 0
                          --> recordJobFinished              --> Event "Completed"
                                                            --> metric job_finished_total
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| job_controller.go | `pkg/controller/job/job_controller.go` | ソース | Jobコントローラーのメインロジック、イベント発行 |
