# 通知設計書 30-handleError（JobLeaderListener）

## 概要

本ドキュメントは、Apache Flink のジョブリーダーサービスエラー通知（handleError - JobLeaderListener）の詳細設計を記載したものである。ジョブリーダーサービスでエラーが発生した際に、JobLeaderListener に通知する仕組みを定義する。

### 本通知の処理概要

**業務上の目的・背景**：タスクマネージャは、実行するジョブのジョブマネージャ（リーダー）を追跡する必要がある。`JobLeaderService` はこの追跡を担当するが、リーダー取得中やジョブマネージャへの登録中にエラーが発生する可能性がある。本通知は、そのようなエラーをタスクエグゼキュータに伝達し、適切な回復処理やシャットダウンを実行できるようにする。

**通知の送信タイミング**：`DefaultJobLeaderService` 内で以下の状況で発生する：
1. `JobManagerLeaderListener.handleError()` - リーダー取得サービスでのエラー
2. `JobManagerRegisteredRpcConnection.onRegistrationFailure()` - ジョブマネージャへの登録失敗

**通知の受信者**：`JobLeaderListener` インターフェースを実装するコンポーネントが受信者となる。代表的な実装として `TaskExecutor.JobLeaderListenerImpl` がある。

**通知内容の概要**：通知には、エラーの原因となった `Throwable` オブジェクトが含まれる。`Exception` ではなく `Throwable` を受け取る点が他のエラーハンドラとの違いである。

**期待されるアクション**：リスナーは、エラーをログに記録し、`onFatalError()` を呼び出してシステムのシャットダウンを開始する。

## 通知種別

内部コールバック通知（Java インターフェースコールバック）

## 送信仕様

### 基本情報

| 項目 | 内容 |
|-----|------|
| 送信方式 | 同期 |
| 優先度 | 高 |
| リトライ | なし |

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

`DefaultJobLeaderService.start()` で登録された `JobLeaderListener` に対して通知が送信される。サービス稼働中のみ通知が行われる。

## 通知テンプレート

### コールバック通知の場合

| 項目 | 内容 |
|-----|------|
| インターフェース | `JobLeaderListener` |
| メソッド | `handleError` |
| 形式 | Java インターフェースコールバック |

### パラメータ

```java
void handleError(Throwable throwable);
```

### 添付ファイル

該当なし

## テンプレート変数

| 変数名 | 説明 | データ取得元 | 必須 |
|--------|------|-------------|-----|
| throwable | エラーの原因 | ジョブリーダーサービス | Yes |

## 送信トリガー・条件

### トリガー一覧

| トリガー種別 | トリガーイベント | 送信条件 | 説明 |
|------------|----------------|---------|------|
| リーダー取得エラー | `JobManagerLeaderListener.handleError()` | サービス稼働中 | リーダー取得サービスからのエラー転送 |
| 登録失敗 | `onRegistrationFailure()` | 有効な登録 | ジョブマネージャへの登録失敗 |

### 送信抑止条件

| 条件 | 説明 |
|-----|------|
| サービス停止 | `stopped` が true の場合 |
| 無効な登録 | リーダーセッションIDが一致しない場合 |

## 処理フロー

### 送信フロー

```mermaid
flowchart TD
    A[ジョブリーダーサービスエラー] --> B{エラー発生箇所}
    B -->|リーダー取得| C[JobManagerLeaderListener.handleError]
    B -->|登録失敗| D[onRegistrationFailure]
    C --> E{stopped?}
    E -->|Yes| F[ログ出力して終了]
    E -->|No| G[jobLeaderListener.handleError]
    D --> H{有効な登録?}
    H -->|No| I[ログ出力して終了]
    H -->|Yes| J[ログ出力]
    J --> G
    G --> K[TaskExecutor.JobLeaderListenerImpl]
    K --> L[onFatalError]
    L --> M[終了]
    F --> M
    I --> M
```

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

### 参照テーブル一覧

該当なし

### メモリ内データ構造

| データ構造 | クラス | 用途 | 備考 |
|-----------|------|------|------|
| jobLeaderListener | `JobLeaderListener` | リスナー参照 | DefaultJobLeaderService |
| stopped | `boolean` | サービス状態 | JobManagerLeaderListener |

### 更新データ一覧

該当なし

## エラー処理

### エラーケース一覧

| エラー種別 | 発生条件 | 対処方法 |
|----------|---------|---------|
| リーダー取得エラー | リーダー取得サービスでの例外 | handleError で通知 |
| 登録失敗 | ジョブマネージャへの登録失敗 | handleError で通知 |

### リトライ仕様

| 項目 | 内容 |
|-----|------|
| リトライ回数 | なし |
| リトライ間隔 | なし |
| リトライ対象エラー | なし |

## 配信設定

### レート制限

| 項目 | 内容 |
|-----|------|
| 1分あたり上限 | 制限なし |
| 1日あたり上限 | 制限なし |

### 配信時間帯

制限なし

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

- 例外メッセージにジョブマネージャ接続情報が含まれる可能性があるため、ログ出力時に注意が必要

## 備考

- `jobManagerGainedLeadership()`, `jobManagerLostLeadership()`, `jobManagerRejectedRegistration()` と同じインターフェースで定義されている
- パラメータは `Throwable` 型であり、`Exception` よりも広い例外を受け取る
- TaskExecutor では `onFatalError()` に転送されることが多い

---

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

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

### 推奨読解順序

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

JobLeaderListener インターフェースの定義を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | JobLeaderListener.java | `flink-runtime/src/main/java/org/apache/flink/runtime/taskexecutor/` | インターフェース定義 |

**読解のコツ**: `JobLeaderListener` は4つのメソッドを持ち、`handleError()` は `Throwable` を受け取る点に注意。

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

インターフェース定義とメソッドシグネチャを理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | JobLeaderListener.java | `flink-runtime/src/main/java/org/apache/flink/runtime/taskexecutor/` | インターフェース定義 |

**主要処理フロー**:
- **行 56-61**: `handleError()` メソッドシグネチャと Javadoc
- パラメータは `Throwable throwable` の1つ

#### Step 3: 通知送信ロジックを理解する

DefaultJobLeaderService でのエラー転送を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | DefaultJobLeaderService.java | `flink-runtime/src/main/java/org/apache/flink/runtime/taskexecutor/` | ジョブリーダーサービス実装 |

**主要処理フロー**:
1. **行 366-378**: `JobManagerLeaderListener.handleError()` - リーダー取得サービスからの転送
2. **行 368-375**: サービス停止時のスキップ処理
3. **行 376**: `jobLeaderListener.handleError(exception)` 呼び出し
4. **行 452-468**: `onRegistrationFailure()` - 登録失敗時の処理
5. **行 460**: `jobLeaderListener.handleError(failure)` 呼び出し

#### Step 4: 受信側の実装を理解する

TaskExecutor での handleError 実装を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | TaskExecutor.java | `flink-runtime/src/main/java/org/apache/flink/runtime/taskexecutor/` | タスクエグゼキュータ |

**主要処理フロー**:
- **行 2566-2569**: `JobLeaderListenerImpl.handleError()` の実装
- **行 2568**: `onFatalError(throwable)` への転送

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

```
ジョブリーダーサービス内のエラー
    │
    ├─ リーダー取得サービスからのエラー
    │      └─ JobManagerLeaderListener.handleError(exception)  [行 366-378]
    │              │
    │              ├─ サービス停止中の場合
    │              │      └─ ログ出力して終了  [行 368-375]
    │              │
    │              └─ サービス稼働中の場合
    │                      └─ jobLeaderListener.handleError(exception)  [行 376]
    │
    └─ ジョブマネージャ登録失敗
            └─ onRegistrationFailure(failure)  [行 452-468]
                    │
                    ├─ 無効な登録の場合
                    │      └─ ログ出力して終了  [行 462-467]
                    │
                    └─ 有効な登録の場合
                            └─ jobLeaderListener.handleError(failure)  [行 460]
                                    │
                                    └─ TaskExecutor.JobLeaderListenerImpl
                                            └─ onFatalError(throwable)  [行 2568]
```

### データフロー図

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

Throwable              ───▶  DefaultJobLeaderService    ───▶  コールバック通知
(サービスエラー)              (エラー転送)                     (Listener へ)
      │                              │                            │
      │                              ▼                            ▼
      │               JobManagerLeaderListener           handleError(throwable)
      │               or onRegistrationFailure           (エラー処理)
      │               (状態確認)                              │
      │                              │                            ▼
      │                              ▼                     onFatalError()
      │                    有効性チェック                  (致命的エラー転送)
      │                              │
      └──────────────────────────────┘
              エラー情報
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| JobLeaderListener.java | `flink-runtime/src/main/java/org/apache/flink/runtime/taskexecutor/` | ソース | インターフェース定義 |
| DefaultJobLeaderService.java | `flink-runtime/src/main/java/org/apache/flink/runtime/taskexecutor/` | ソース | ジョブリーダーサービス |
| TaskExecutor.java | `flink-runtime/src/main/java/org/apache/flink/runtime/taskexecutor/` | ソース | Listener 実装 |
| JobLeaderService.java | `flink-runtime/src/main/java/org/apache/flink/runtime/taskexecutor/` | ソース | サービスインターフェース |
