# 通知設計書 29-handleError（LeaderRetrievalListener）

## 概要

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

### 本通知の処理概要

**業務上の目的・背景**：Flink の分散システムにおいて、コンポーネントは他のコンポーネント（例：ResourceManager、JobMaster）のリーダー情報を取得する必要がある。リーダー取得サービスがバックエンド（ZooKeeper 等）との通信中にエラーが発生した場合、リスナーに適切に通知し、回復処理やフェイルオーバーを実行できるようにする必要がある。

**通知の送信タイミング**：`DefaultLeaderRetrievalService` 内の `LeaderRetrievalFatalErrorHandler` が `onFatalError()` を受信し、それを `LeaderRetrievalListener.handleError()` に転送する際に発生する。具体的には、リーダー取得ドライバーでの予期しない例外がキャッチされた場合である。

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

**通知内容の概要**：通知には、エラーの原因となった `Exception` オブジェクトが含まれる。多くの場合、`LeaderRetrievalException` でラップされる。

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

## 通知種別

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

## 送信仕様

### 基本情報

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

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

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

## 通知テンプレート

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

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

### パラメータ

```java
void handleError(Exception exception);
```

### 添付ファイル

該当なし

## テンプレート変数

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

## 送信トリガー・条件

### トリガー一覧

| トリガー種別 | トリガーイベント | 送信条件 | 説明 |
|------------|----------------|---------|------|
| ドライバーエラー | LeaderRetrievalDriver 例外 | サービス稼働中 | バックエンドとの通信エラー |
| 接続エラー | ZooKeeper 等との接続失敗 | サービス稼働中 | ネットワークエラー |

### 送信抑止条件

| 条件 | 説明 |
|-----|------|
| サービス停止 | `running` が false の場合 |

## 処理フロー

### 送信フロー

```mermaid
flowchart TD
    A[リーダー取得ドライバーエラー] --> B[LeaderRetrievalFatalErrorHandler.onFatalError]
    B --> C{サービス稼働中?}
    C -->|No| D[ログ出力して終了]
    C -->|Yes| E{LeaderRetrievalException?}
    E -->|Yes| F[そのまま handleError に渡す]
    E -->|No| G[LeaderRetrievalException でラップ]
    G --> H[leaderListener.handleError]
    F --> H
    H --> I[リスナー側でのエラー処理]
    I --> J{TaskExecutor の場合}
    J -->|Yes| K[onFatalError 呼び出し]
    J -->|No| L[その他のエラー処理]
    K --> M[終了]
    L --> M
    D --> M
```

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

### 参照テーブル一覧

該当なし

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

| データ構造 | クラス | 用途 | 備考 |
|-----------|------|------|------|
| leaderListener | `LeaderRetrievalListener` | リスナー参照 | DefaultLeaderRetrievalService |
| running | `boolean` | サービス状態 | DefaultLeaderRetrievalService |

### 更新データ一覧

該当なし

## エラー処理

### エラーケース一覧

| エラー種別 | 発生条件 | 対処方法 |
|----------|---------|---------|
| 接続エラー | バックエンド到達不能 | handleError で通知 |
| 内部エラー | 予期しない例外 | LeaderRetrievalException でラップして通知 |

### リトライ仕様

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

## 配信設定

### レート制限

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

### 配信時間帯

制限なし

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

- 例外メッセージにバックエンド接続情報が含まれる可能性があるため、ログ出力時に注意が必要

## 備考

- `notifyLeaderAddress()` と同じインターフェースで定義されている
- 例外は `LeaderRetrievalException` でラップされることが多い
- TaskExecutor では `onFatalError()` に転送されることが多い

---

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

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

### 推奨読解順序

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

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | LeaderRetrievalListener.java | `flink-runtime/src/main/java/org/apache/flink/runtime/leaderretrieval/` | インターフェース定義 |
| 1-2 | LeaderRetrievalException.java | `flink-runtime/src/main/java/org/apache/flink/runtime/leaderretrieval/` | 例外クラス |

**読解のコツ**: `LeaderRetrievalListener` は `notifyLeaderAddress()` と `handleError()` の2つのメソッドを持つ。

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

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

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

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

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

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | DefaultLeaderRetrievalService.java | `flink-runtime/src/main/java/org/apache/flink/runtime/leaderretrieval/` | リーダー取得サービス実装 |

**主要処理フロー**:
1. **行 161-181**: `LeaderRetrievalFatalErrorHandler` 内部クラス
2. **行 163-179**: `onFatalError()` メソッド
3. **行 166-172**: サービス停止時のスキップ処理
4. **行 174-178**: LeaderRetrievalException でのラップと通知

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

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

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

**主要処理フロー**:
- **行 2523-2526**: `ResourceManagerLeaderListener.handleError()` の実装
- **行 2525**: `onFatalError(exception)` への転送

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

```
LeaderRetrievalDriver（バックエンド）
    │
    └─ エラー発生
            └─ FatalErrorHandler.onFatalError(Throwable)
                    └─ DefaultLeaderRetrievalService.LeaderRetrievalFatalErrorHandler
                            .onFatalError(throwable)  [行 163-179]
                            │
                            ├─ サービス停止中の場合
                            │      └─ ログ出力して終了  [行 166-172]
                            │
                            └─ サービス稼働中の場合
                                    │
                                    ├─ LeaderRetrievalException の場合
                                    │      └─ handleError(exception)  [行 175]
                                    │
                                    └─ その他の例外の場合
                                           └─ handleError(new LeaderRetrievalException(throwable))  [行 177]
                                                   │
                                                   └─ LeaderRetrievalListener 実装
                                                           │
                                                           └─ TaskExecutor.ResourceManagerLeaderListener
                                                                   └─ onFatalError(exception)  [行 2525]
```

### データフロー図

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

Throwable              ───▶  DefaultLeaderRetrievalService ───▶  コールバック通知
(ドライバーエラー)            (エラー転送)                       (Listener へ)
      │                              │                            │
      │                              ▼                            ▼
      │               LeaderRetrievalFatalErrorHandler     handleError(exception)
      │               (稼働状態確認)                        (エラー処理)
      │                              │                            │
      │                              ▼                            ▼
      │               LeaderRetrievalException             onFatalError()
      │               (例外ラップ)                          (致命的エラー転送)
      │                              │
      └──────────────────────────────┘
              エラー情報
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| LeaderRetrievalListener.java | `flink-runtime/src/main/java/org/apache/flink/runtime/leaderretrieval/` | ソース | インターフェース定義 |
| DefaultLeaderRetrievalService.java | `flink-runtime/src/main/java/org/apache/flink/runtime/leaderretrieval/` | ソース | リーダー取得サービス |
| LeaderRetrievalException.java | `flink-runtime/src/main/java/org/apache/flink/runtime/leaderretrieval/` | ソース | 例外クラス |
| TaskExecutor.java | `flink-runtime/src/main/java/org/apache/flink/runtime/taskexecutor/` | ソース | Listener 実装 |
| DefaultJobLeaderService.java | `flink-runtime/src/main/java/org/apache/flink/runtime/taskexecutor/` | ソース | Listener 実装 |
