# 通知設計書 12-notifyTargetUnreachable

## 概要

本ドキュメントは、Apache Flinkのターゲット到達不能通知（notifyTargetUnreachable）の設計仕様を記述したものである。

### 本通知の処理概要

notifyTargetUnreachableは、ハートビートRPCが連続して失敗した場合にリスナーに通知するメカニズムである。タイムアウトとは異なり、ネットワーク障害やターゲットノードへの到達不能状態を検知するために使用される。

**業務上の目的・背景**：分散システムでは、ハートビートのタイムアウトを待つよりも、RPC失敗の連続発生を検知することで、より迅速にノード障害を検出できる。これにより、フェイルオーバー処理の開始を早め、システムの可用性を向上させることができる。

**通知の送信タイミング**：HeartbeatMonitorがハートビートRPC失敗を検知し、連続失敗回数がfailedRpcRequestsUntilUnreachable閾値に達した時点で通知が発行される。具体的には、reportHeartbeatRpcFailure()メソッドが呼び出されるたびに失敗カウンタがインクリメントされ、閾値到達時にコールバックが実行される。

**通知の受信者**：HeartbeatListenerインターフェースを実装するクラス（ResourceManager、JobMaster、TaskExecutor）が受信者となる。

**通知内容の概要**：到達不能となったノードのResourceID（リソース識別子）が通知される。

**期待されるアクション**：受信者は、到達不能となったノードとの接続を即座に切断し、リソースの再配置やジョブのリカバリ処理を開始する。タイムアウト通知よりも迅速な障害対応が期待される。

## 通知種別

内部コールバック（Javaメソッド呼び出し）

## 送信仕様

### 基本情報

| 項目 | 内容 |
|-----|------|
| 送信方式 | 同期（RPC失敗検知スレッドから呼び出し） |
| 優先度 | 高（障害検知に直結） |
| リトライ | なし（1回限りの通知） |

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

HeartbeatManagerに登録されたHeartbeatListenerに対して通知される。リスナーは各コンポーネントの初期化時に登録される。

## 通知テンプレート

### コールバックシグネチャ

```java
void notifyTargetUnreachable(ResourceID resourceID);
```

### パラメータ詳細

| パラメータ名 | 型 | 説明 |
|------------|-----|------|
| resourceID | ResourceID | 到達不能となったノードのリソース識別子 |

## テンプレート変数

| 変数名 | 説明 | データ取得元 | 必須 |
|--------|------|-------------|-----|
| resourceID | 到達不能ノードのID | HeartbeatMonitorが保持 | Yes |

## 送信トリガー・条件

### トリガー一覧

| トリガー種別 | トリガーイベント | 送信条件 | 説明 |
|------------|----------------|---------|------|
| RPC失敗 | ハートビートRPC失敗 | 連続失敗回数が閾値に到達 | reportHeartbeatRpcFailure()呼び出し時に判定 |

### 送信抑止条件

| 条件 | 説明 |
|-----|------|
| 状態がRUNNING以外 | 既にUNREACHABLEやCANCELED状態では通知されない |
| RPC失敗検知が無効 | failedRpcRequestsUntilUnreachableが-1の場合、機能が無効 |
| RPC成功 | 成功時にカウンタがリセットされるため、閾値到達がリセット |

## 処理フロー

### 送信フロー

```mermaid
flowchart TD
    A[ハートビートRPC実行] --> B{RPC結果}
    B -->|成功| C[失敗カウンタリセット]
    C --> A
    B -->|失敗| D[失敗カウンタインクリメント]
    D --> E{閾値到達?}
    E -->|No| A
    E -->|Yes| F{状態がRUNNING?}
    F -->|Yes| G[状態をUNREACHABLEに変更]
    G --> H[タイマーキャンセル]
    H --> I[notifyTargetUnreachable呼び出し]
    F -->|No| J[処理終了]
    I --> J
```

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

### 参照テーブル一覧

データベースアクセスは発生しない（インメモリ処理）。

### 更新テーブル一覧

データベース更新は発生しない。

## エラー処理

### エラーケース一覧

| エラー種別 | 発生条件 | 対処方法 |
|----------|---------|---------|
| リスナー例外 | notifyTargetUnreachable内で例外発生 | ログ出力して処理継続 |
| 状態不整合 | CAS操作失敗 | 処理をスキップ |

### リトライ仕様

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

## 配信設定

### レート制限

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

### 配信時間帯

時間帯の制限なし（24時間稼働）

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

- ResourceIDは内部識別子であり、機密情報は含まれない
- 通知はJVM内部のメソッド呼び出しで完結

## 備考

- 連続RPC失敗回数の閾値はHeartbeatManagerOptions.FAILED_RPC_DETECTION_DISABLEDで無効化可能
- タイムアウト通知と到達不能通知は排他的（どちらか一方のみ発生）

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | ResourceID.java | `flink-runtime/src/main/java/org/apache/flink/runtime/clusterframework/types/ResourceID.java` | ノード識別子の構造 |

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | HeartbeatListener.java | `flink-runtime/src/main/java/org/apache/flink/runtime/heartbeat/HeartbeatListener.java` | インターフェース定義（46-52行目） |

**主要処理フロー**:
1. **行46-52**: notifyTargetUnreachableメソッドのJavadoc定義
2. **行52**: void notifyTargetUnreachable(ResourceID resourceID) シグネチャ

#### Step 3: 実装クラスを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | DefaultHeartbeatMonitor.java | `flink-runtime/src/main/java/org/apache/flink/runtime/heartbeat/DefaultHeartbeatMonitor.java` | RPC失敗検知の実装（113-129行目） |

**主要処理フロー**:
- **行113-129**: reportHeartbeatRpcFailure()メソッド
- **行119**: 状態遷移（RUNNING -> UNREACHABLE）
- **行126**: notifyTargetUnreachable呼び出し

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

```
HeartbeatRPC失敗検知
    │
    └─ DefaultHeartbeatMonitor.reportHeartbeatRpcFailure()
           │
           ├─ numberFailedRpcRequestsSinceLastSuccess.incrementAndGet()
           │
           ├─ isHeartbeatRpcFailureDetectionEnabled() チェック
           │
           ├─ 閾値到達判定
           │
           ├─ state.compareAndSet(RUNNING, UNREACHABLE)
           │
           ├─ cancelTimeout()
           │
           └─ HeartbeatListener.notifyTargetUnreachable(resourceID)
```

### データフロー図

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

RPC失敗検知 ───▶ DefaultHeartbeatMonitor ───▶ HeartbeatListener
                       │                          │
                       ├─ 失敗カウンタ管理         └─ 障害処理開始
                       └─ 閾値チェック
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| HeartbeatListener.java | `flink-runtime/src/main/java/org/apache/flink/runtime/heartbeat/HeartbeatListener.java` | インターフェース | リスナーインターフェース定義 |
| DefaultHeartbeatMonitor.java | `flink-runtime/src/main/java/org/apache/flink/runtime/heartbeat/DefaultHeartbeatMonitor.java` | 実装クラス | RPC失敗検知とコールバック発行 |
| HeartbeatManagerOptions.java | `flink-runtime/src/main/java/org/apache/flink/configuration/HeartbeatManagerOptions.java` | 設定 | 閾値設定オプション |
| ResourceManager.java | `flink-runtime/src/main/java/org/apache/flink/runtime/resourcemanager/ResourceManager.java` | リスナー実装 | リソース管理側の処理 |
| JobMaster.java | `flink-runtime/src/main/java/org/apache/flink/runtime/jobmaster/JobMaster.java` | リスナー実装 | ジョブ管理側の処理 |
| TaskExecutor.java | `flink-runtime/src/main/java/org/apache/flink/runtime/taskexecutor/TaskExecutor.java` | リスナー実装 | タスク実行側の処理 |
