# 通知設計書 28-handleError（LeaderContender）

## 概要

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

### 本通知の処理概要

**業務上の目的・背景**：Flink の高可用性機能において、リーダー選出は重要な役割を果たす。ZooKeeper や Kubernetes などのバックエンドとの通信中にエラーが発生した場合、リーダー候補者（LeaderContender）に適切に通知し、回復処理やフェイルオーバーを実行できるようにする必要がある。本通知は、リーダー選出プロセスにおけるエラーハンドリングの中核を担う。

**通知の送信タイミング**：`DefaultLeaderElectionService` または `LeaderElectionDriver` でエラーが発生した際に発生する。具体的には、バックエンドとの接続エラー、リーダー情報の読み書きエラー、または予期しない例外がキャッチされた場合である。

**通知の受信者**：`LeaderContender` インターフェースを実装するコンポーネントが受信者となる。代表的な実装として `JobMasterServiceLeadershipRunner`、`ResourceManagerServiceImpl`、`DefaultDispatcherRunner` などがある。

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

**期待されるアクション**：LeaderContender は、エラーをログに記録し、必要に応じてリーダーシップの放棄やサービスの再起動を行う。

## 通知種別

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

## 送信仕様

### 基本情報

| 項目 | 内容 |
|-----|------|
| 送信方式 | 非同期（Executor 経由） |
| 優先度 | 高 |
| リトライ | なし |

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

`DefaultLeaderElectionService` に登録された `LeaderContender` に対して通知が送信される。複数の Contender が登録されている場合、すべての Contender に対して通知が行われる。

## 通知テンプレート

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

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

### パラメータ

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

### 添付ファイル

該当なし

## テンプレート変数

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

## 送信トリガー・条件

### トリガー一覧

| トリガー種別 | トリガーイベント | 送信条件 | 説明 |
|------------|----------------|---------|------|
| 接続エラー | バックエンド接続失敗 | Contender 登録済み | ZooKeeper 等との接続エラー |
| 読み書きエラー | リーダー情報操作失敗 | Contender 登録済み | ノード操作の失敗 |
| 内部エラー | 予期しない例外 | Contender 登録済み | その他の例外 |

### 送信抑止条件

| 条件 | 説明 |
|-----|------|
| Contender 未登録 | `leaderContenderRegistry` が空の場合、fallbackErrorHandler が使用される |
| サービス停止 | サービスが running 状態でない場合 |

## 処理フロー

### 送信フロー

```mermaid
flowchart TD
    A[リーダー選出サービスエラー] --> B[onError コールバック]
    B --> C[forwardErrorToLeaderContender]
    C --> D{Contender 登録済み?}
    D -->|No| E[fallbackErrorHandler.onFatalError]
    D -->|Yes| F[全 Contender に通知]
    F --> G{LeaderElectionException?}
    G -->|Yes| H[そのまま handleError に渡す]
    G -->|No| I[LeaderElectionException でラップ]
    I --> J[leaderContender.handleError]
    H --> J
    J --> K[終了]
    E --> K
```

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

### 参照テーブル一覧

該当なし

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

| データ構造 | クラス | 用途 | 備考 |
|-----------|------|------|------|
| leaderContenderRegistry | `Map<String, LeaderContender>` | Contender 管理 | DefaultLeaderElectionService |

### 更新データ一覧

該当なし

## エラー処理

### エラーケース一覧

| エラー種別 | 発生条件 | 対処方法 |
|----------|---------|---------|
| 接続エラー | バックエンド到達不能 | handleError で通知 |
| ノードエラー | リーダー情報ノード操作失敗 | handleError で通知 |
| 内部エラー | 予期しない例外 | LeaderElectionException でラップして通知 |

### リトライ仕様

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

## 配信設定

### レート制限

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

### 配信時間帯

制限なし

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

- 例外メッセージにバックエンド接続情報が含まれる可能性があるため、ログ出力時に注意が必要
- ZooKeeper 認証情報等が例外に含まれないことを確認する

## 備考

- `grantLeadership()` および `revokeLeadership()` と同じインターフェースで定義されている
- 例外は `LeaderElectionException` でラップされることが多い
- Contender が未登録の場合は `fallbackErrorHandler` にフォールバックする

---

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

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

### 推奨読解順序

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

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

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

**読解のコツ**: `LeaderContender` は `grantLeadership()`, `revokeLeadership()`, `handleError()` の3つのメソッドを持つ。

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

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

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

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

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

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

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

**主要処理フロー**:
1. **行 577-595**: `forwardErrorToLeaderContender()` メソッド
2. **行 579-582**: Contender 未登録時のフォールバック
3. **行 584-594**: 全 Contender への通知ループ
4. **行 588-591**: LeaderElectionException でのラップ処理
5. **行 640-642**: `onError()` コールバック

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

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | JobMasterServiceLeadershipRunner.java | `flink-runtime/src/main/java/org/apache/flink/runtime/jobmaster/` | ジョブマスターリーダーシップランナー |

**主要処理フロー**:
- handleError でのエラーログ出力とシャットダウン処理

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

```
LeaderElectionDriver（バックエンド）
    │
    └─ エラー発生
            └─ DefaultLeaderElectionService.onError(Throwable)  [行 640-642]
                    └─ forwardErrorToLeaderContender(t)  [行 577-595]
                            │
                            ├─ Contender 未登録の場合
                            │      └─ fallbackErrorHandler.onFatalError(t)  [行 580]
                            │
                            └─ Contender 登録済みの場合
                                    └─ 全 Contender をループ  [行 584-594]
                                            │
                                            ├─ LeaderElectionException の場合
                                            │      └─ handleError(exception)  [行 589]
                                            │
                                            └─ その他の例外の場合
                                                   └─ handleError(new LeaderElectionException(t))  [行 591]
                                                           │
                                                           └─ LeaderContender 実装
                                                                   └─ エラー処理実行
```

### データフロー図

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

Throwable              ───▶  DefaultLeaderElectionService ───▶  コールバック通知
(バックエンドエラー)          (エラー転送)                      (LeaderContender へ)
      │                              │                            │
      │                              ▼                            ▼
      │               forwardErrorToLeaderContender       handleError(exception)
      │               (Contender 確認)                     (エラー処理)
      │                              │                            │
      │                              ▼                            ▼
      │               LeaderElectionException             ログ出力/シャットダウン
      │               (例外ラップ)
      │                              │
      └──────────────────────────────┘
              エラー情報
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| LeaderContender.java | `flink-runtime/src/main/java/org/apache/flink/runtime/leaderelection/` | ソース | インターフェース定義 |
| DefaultLeaderElectionService.java | `flink-runtime/src/main/java/org/apache/flink/runtime/leaderelection/` | ソース | リーダー選出サービス |
| LeaderElectionException.java | `flink-runtime/src/main/java/org/apache/flink/runtime/leaderelection/` | ソース | 例外クラス |
| JobMasterServiceLeadershipRunner.java | `flink-runtime/src/main/java/org/apache/flink/runtime/jobmaster/` | ソース | Contender 実装 |
| ResourceManagerServiceImpl.java | `flink-runtime/src/main/java/org/apache/flink/runtime/resourcemanager/` | ソース | Contender 実装 |
| DefaultDispatcherRunner.java | `flink-runtime/src/main/java/org/apache/flink/runtime/dispatcher/runner/` | ソース | Contender 実装 |
