# 通知設計書 106-Resumed

## 概要

本ドキュメントは、KubernetesのJobコントローラーが発行する「Resumed」イベント通知の設計を記述する。一時停止されていたJobが再開された際にNormalイベントとして発行される。

### 本通知の処理概要

Jobコントローラーの同期処理内で、Jobのspec.suspendフィールドがfalseに変更され、status.conditionsのJobSuspended条件がConditionFalseに更新された場合に発行されるNormalイベントである。

**業務上の目的・背景**：Jobの再開はワークロード管理の重要な操作である。この通知により、運用者がJobの再開を検知し、ワークロードの実行状態を把握できる。再開時にはStartTimeがリセットされるため、ActiveDeadlineSecondsのタイマーも再開時刻からカウントされる。

**通知の送信タイミング**：Jobコントローラーのsync処理内で`manageJob`が呼び出された後、Jobがsuspend状態でなく、かつJobSuspended条件がConditionFalseに新たに設定された場合に発行される。具体的には`job_controller.go`の1060行目で発行される。

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

**通知内容の概要**：「Job resumed」というメッセージが含まれ、Jobが再開されたことを通知する。

**期待されるアクション**：Jobの再開を確認し、期待通りにPodが作成されているかを監視する。必要に応じてジョブの進捗を確認する。

## 通知種別

Kubernetes Event（Normal）

## 送信仕様

### 基本情報

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

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

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

## 通知テンプレート

### Kubernetes Eventの場合

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

### 本文テンプレート

```
Job resumed
```

### 添付ファイル

該当なし

## テンプレート変数

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

## 送信トリガー・条件

### トリガー一覧

| トリガー種別 | トリガーイベント | 送信条件 | 説明 |
|------------|----------------|---------|------|
| コントローラー同期 | Jobのsync処理 | jobSuspended == false かつ JobSuspended条件がConditionFalseに新たに設定 | ensureJobConditionStatusの戻り値isUpdated == true |

### 送信抑止条件

| 条件 | 説明 |
|-----|------|
| 既にResumed状態 | JobSuspended条件が既にConditionFalseの場合、isUpdated=falseとなりイベントは発行されない |
| Jobが完了済み | complete=trueの場合 |
| manageJobが呼び出されていない | manageJobCalledがfalseの場合 |

## 処理フロー

### 送信フロー

```mermaid
flowchart TD
    A[Job sync開始] --> B[manageJob呼び出し]
    B --> C{complete?}
    C -->|Yes| D[完了処理]
    C -->|No| E{manageJobCalled?}
    E -->|No| F[終了]
    E -->|Yes| G{jobSuspended?}
    G -->|Yes| H[Suspended処理]
    G -->|No| I[ensureJobConditionStatus JobSuspended=False]
    I --> J{isUpdated?}
    J -->|Yes| K[Resumed Event発行]
    J -->|No| L[イベントなし]
    K --> M[StartTime=現在時刻に設定]
```

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

### 参照テーブル一覧

| テーブル名 | 用途 | 備考 |
|-----------|------|------|
| Jobオブジェクト | suspend状態の確認 | etcd経由 |

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

#### Jobオブジェクト

| 参照項目（フィールド名） | 用途 | 取得条件 |
|-------------------|------|---------|
| spec.suspend | 一時停止状態の判定 | sync時 |
| status.conditions | 既存JobSuspended条件の確認 | sync時 |

### 更新テーブル一覧

| テーブル名 | 操作 | 概要 |
|-----------|------|------|
| Jobオブジェクト | UPDATE | status.conditionsのJobSuspended=False、startTimeを現在時刻に設定 |
| Eventオブジェクト | INSERT | Resumedイベントの記録 |

## エラー処理

### エラーケース一覧

| エラー種別 | 発生条件 | 対処方法 |
|----------|---------|---------|
| ステータス更新失敗 | APIサーバー接続エラー | requeueして再試行 |

### リトライ仕様

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

## 配信設定

### レート制限

| 項目 | 内容 |
|-----|------|
| 1分あたり上限 | Kubernetes Event APIのレート制限に依存 |
| 1日あたり上限 | 制限なし |

### 配信時間帯

制限なし。

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

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

## 備考

- 再開時にStartTimeが現在時刻にリセットされる（1067-1068行目）。これはActiveDeadlineSecondsが一時停止中はカウントされないことを保証する
- 一時停止状態で作成されたJobについても、再開時にStartTimeが設定される

---

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

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

### 推奨読解順序

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

JobのSuspend関連フィールドを理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | types.go | `vendor/k8s.io/api/batch/v1/types.go` | JobSpec.Suspend、JobConditionType(JobSuspended) |

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | job_controller.go | `pkg/controller/job/job_controller.go` | syncJob内のresume判定（1054-1069行目） |

**主要処理フロー**:
1. **1054行目**: else節（jobSuspendedがfalse）
2. **1057行目**: `ensureJobConditionStatus`でJobSuspended条件をFalse設定
3. **1058行目**: isUpdatedがtrueの場合
4. **1060行目**: `recorder.Event`で"Resumed"イベント発行
5. **1067-1068行目**: StartTimeを現在時刻に設定

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

```
Controller.syncJob
    |
    +-- manageJob
    |
    +-- !jobSuspended判定 (1054行目)
            |
            +-- ensureJobConditionStatus (1057行目)
                    |
                    +-- recorder.Event "Resumed" (1060行目)
                    +-- StartTime = now (1067-1068行目)
```

### データフロー図

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

Job.spec.suspend=false    --> syncJob
                              !jobSuspended判定
Job.status.conditions     --> ensureJobConditionStatus
                              isUpdated=true               --> Event "Resumed"
                                                           --> Job.status.startTime=now
```

### 関連ファイル一覧

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