# 通知設計書 27-onFatalError

## 概要

本ドキュメントは、Apache Flink の致命的エラー通知（onFatalError）の詳細設計を記載したものである。致命的なエラーが発生した際に、`FatalErrorHandler` インターフェースを通じてエラーハンドラに通知する仕組みを定義する。

### 本通知の処理概要

**業務上の目的・背景**：分散システムにおいて、回復不可能な致命的エラーが発生した場合、システムは適切にシャットダウンするか、管理者に通知する必要がある。本通知は、Flink コンポーネント全体で共通的に使用される致命的エラーのハンドリング機構であり、エラーの伝播と適切なシャットダウン処理を実現する。

**通知の送信タイミング**：回復不可能なエラーが検出された際に発生する。例えば、RPC エンドポイントでの予期しない例外、リソースマネージャとの接続失敗、リーダー選出サービスでのエラーなど、システムの正常動作を継続できない状況で呼び出される。

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

**通知内容の概要**：通知には、致命的エラーの原因となった `Throwable` オブジェクトが含まれる。例外チェーンを辿ることで、エラーの根本原因を特定できる。

**期待されるアクション**：エラーハンドラは、エラーをログに記録し、必要に応じてプロセスを終了するか、クラスタをシャットダウンする。この呼び出しはブロッキングであってはならず、即座に制御を返す必要がある。

## 通知種別

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

## 送信仕様

### 基本情報

| 項目 | 内容 |
|-----|------|
| 送信方式 | 同期（ノンブロッキング必須） |
| 優先度 | 最高 |
| リトライ | なし |

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

各コンポーネントのコンストラクタまたは初期化時に `FatalErrorHandler` が注入され、エラー発生時にその `onFatalError()` メソッドが呼び出される。

## 通知テンプレート

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

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

### パラメータ

```java
void onFatalError(Throwable exception);
```

### 添付ファイル

該当なし

## テンプレート変数

| 変数名 | 説明 | データ取得元 | 必須 |
|--------|------|-------------|-----|
| exception | 致命的エラーの原因 | エラー発生箇所 | Yes |

## 送信トリガー・条件

### トリガー一覧

| トリガー種別 | トリガーイベント | 送信条件 | 説明 |
|------------|----------------|---------|------|
| RPC エラー | RpcEndpoint 例外 | 回復不可能 | RPC 処理での予期しない例外 |
| 登録失敗 | リソースマネージャ登録失敗 | 最終失敗 | リトライ後の最終的な失敗 |
| リーダー選出エラー | リーダー選出サービス例外 | エラー発生 | ZooKeeper 等との接続エラー |
| タスク実行エラー | タスク実行中の致命的エラー | 回復不可能 | メモリ不足等のシステムエラー |

### 送信抑止条件

| 条件 | 説明 |
|-----|------|
| 特になし | 致命的エラーは常に通知される |

## 処理フロー

### 送信フロー

```mermaid
flowchart TD
    A[致命的エラー発生] --> B[例外をキャッチ]
    B --> C[fatalErrorHandler.onFatalError]
    C --> D[エラーログ出力]
    D --> E{ハンドラ実装}
    E -->|ClusterEntrypoint| F[System.exit 呼び出し]
    E -->|TaskManagerRunner| G[タスクマネージャ停止]
    E -->|MiniCluster| H[クラスタシャットダウン]
    F --> I[プロセス終了]
    G --> I
    H --> I
```

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

### 参照テーブル一覧

該当なし

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

該当なし

### 更新データ一覧

該当なし

## エラー処理

### エラーケース一覧

| エラー種別 | 発生条件 | 対処方法 |
|----------|---------|---------|
| ハンドラ内例外 | エラーハンドリング中の例外 | ベストエフォートで処理継続 |

### リトライ仕様

| 項目 | 内容 |
|-----|------|
| リトライ回数 | なし |
| リトライ間隔 | なし |
| リトライ対象エラー | なし（致命的エラーはリトライ不可） |

## 配信設定

### レート制限

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

### 配信時間帯

制限なし

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

- 例外メッセージにセンシティブな情報が含まれる可能性があるため、ログ出力時に注意が必要
- スタックトレースはデバッグ目的で有用だが、本番環境では適切なログレベル設定が推奨される

## 備考

- **重要**: この呼び出しはブロッキングであってはならない（Javadoc に明記）
- RpcEndpoint のメインスレッドから呼び出される可能性があるため、デッドロックを避ける設計が必要
- 多くのコンポーネントで共通的に使用される汎用インターフェース

---

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

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

### 推奨読解順序

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

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

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

**読解のコツ**: Javadoc に「IMPORTANT: This call should never be blocking」と明記されている点に注目。

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

インターフェース定義とブロッキング禁止の制約を理解する。

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

**主要処理フロー**:
- **行 21-22**: インターフェースの目的説明
- **行 24-32**: `onFatalError()` メソッドとその Javadoc

#### Step 3: 呼び出し元を理解する

TaskExecutor での onFatalError 呼び出しを理解する。

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

**主要処理フロー**:
- **行 2453-2460**: `onFatalError()` メソッド実装
- **行 476, 1025, 1050** など: 各種エラー発生箇所からの呼び出し

#### Step 4: ハンドラ実装を理解する

ClusterEntrypoint での FatalErrorHandler 実装を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | ClusterEntrypoint.java | `flink-runtime/src/main/java/org/apache/flink/runtime/entrypoint/` | クラスタエントリポイント |

**主要処理フロー**:
- エラーログ出力
- System.exit() 呼び出しによるプロセス終了

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

```
各種コンポーネント（エラー発生箇所）
    │
    ├─ TaskExecutor.onFatalError()  [行 2453-2460]
    │      └─ fatalErrorHandler.onFatalError(t)  [行 2460]
    │
    ├─ ResourceManager.onFatalError()
    │      └─ fatalErrorHandler.onFatalError(t)
    │
    ├─ JobMaster.onFatalError()
    │      └─ fatalErrorHandler.onFatalError(t)
    │
    └─ Dispatcher.onFatalError()
            └─ fatalErrorHandler.onFatalError(t)
                    │
                    └─ FatalErrorHandler 実装
                            │
                            ├─ ClusterEntrypoint
                            │      └─ System.exit()
                            │
                            ├─ TaskManagerRunner
                            │      └─ タスクマネージャ停止
                            │
                            └─ MiniCluster
                                   └─ クラスタシャットダウン
```

### データフロー図

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

Throwable              ───▶  FatalErrorHandler         ───▶  システム終了
(致命的例外)                  (エラーハンドリング)            (プロセス停止)
      │                              │                            │
      │                              ▼                            ▼
      │               log.error()                         System.exit()
      │               (エラーログ出力)                     (プロセス終了)
      │                              │
      │                              ▼
      │               例外チェーン解析
      │               (根本原因特定)
      │                              │
      └──────────────────────────────┘
              エラー情報
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| FatalErrorHandler.java | `flink-rpc/flink-rpc-core/src/main/java/org/apache/flink/runtime/rpc/` | ソース | インターフェース定義 |
| TaskExecutor.java | `flink-runtime/src/main/java/org/apache/flink/runtime/taskexecutor/` | ソース | 呼び出し元（タスクエグゼキュータ） |
| ClusterEntrypoint.java | `flink-runtime/src/main/java/org/apache/flink/runtime/entrypoint/` | ソース | ハンドラ実装（クラスタ） |
| TaskManagerRunner.java | `flink-runtime/src/main/java/org/apache/flink/runtime/taskexecutor/` | ソース | ハンドラ実装（タスクマネージャ） |
| MiniCluster.java | `flink-runtime/src/main/java/org/apache/flink/runtime/minicluster/` | ソース | ハンドラ実装（ミニクラスタ） |
| ResourceManager.java | `flink-runtime/src/main/java/org/apache/flink/runtime/resourcemanager/` | ソース | 呼び出し元（リソースマネージャ） |
| JobMaster.java | `flink-runtime/src/main/java/org/apache/flink/runtime/jobmaster/` | ソース | 呼び出し元（ジョブマスター） |
| Dispatcher.java | `flink-runtime/src/main/java/org/apache/flink/runtime/dispatcher/` | ソース | 呼び出し元（ディスパッチャー） |
