# 通知設計書 23-absl::Notification（スレッド同期）

## 概要

本ドキュメントは、TensorFlowのC++コアランタイムで広範に使用される`absl::Notification`プリミティブの通知設計について記載する。これはAbseil C++ライブラリが提供するスレッド間同期メカニズムであり、TensorFlow内部の非同期処理やイベント完了通知に使用される。

### 本通知の処理概要

absl::Notificationは、あるスレッドから別のスレッドへの完了通知を実現する低レベル同期プリミティブである。Notify()メソッドで通知を発行し、WaitForNotification()メソッドで通知を待ち受ける。一度通知されると、以降のWaitForNotification()は即座に返る。

**業務上の目的・背景**：TensorFlowのC++ランタイムは高度に並行化されており、グラフ実行、デバイスイベント管理、セッション制御など多くの場面でスレッド間の完了同期が必要となる。absl::Notificationは、これらの場面で「一度だけ発火する完了シグナル」として使用され、条件変数やミューテックスの直接操作よりもシンプルで安全なスレッド同期を提供する。

**通知の送信タイミング**：非同期処理の完了時にNotify()が呼ばれる。TensorFlowでの主な使用パターンとして、(1) DirectSessionでのPartialRun完了通知（executors_done）、(2) DeviceEventManagerでのポーリング停止通知（polling_stopped_）、(3) 各種テストでの非同期操作完了待ちがある。

**通知の受信者**：同一プロセス内のWaitForNotification()を呼び出しているスレッドが受信者となる。1つのNotificationオブジェクトに対して複数のスレッドが待機可能である。

**通知内容の概要**：absl::Notificationは「完了した」という二値状態のみを伝達する。追加のデータペイロードは含まない。データの受け渡しが必要な場合は、別途共有メモリやキューを使用する。

**期待されるアクション**：WaitForNotification()から復帰したスレッドは、関連するリソースの後処理や次の処理段階への遷移を行う。タイムアウト付き待機（WaitForNotificationWithTimeout）を使用する場合は、タイムアウト時のキャンセル処理を実行する。

## 通知種別

プロセス内スレッド間同期（メモリ内シグナル）

## 送信仕様

### 基本情報

| 項目 | 内容 |
|-----|------|
| 送信方式 | 同期（Notify()は即座に完了、WaitForNotification()はブロッキング） |
| 優先度 | 高（スレッド同期はランタイムの基盤機能） |
| リトライ | 無し（一度だけ発火する） |

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

送信先はNotificationオブジェクトを共有するすべてのスレッドである。Notify()の呼び出しにより、WaitForNotification()でブロッキングしている全スレッドが起床する。

## 通知テンプレート

### メモリ内通知の場合

| 項目 | 内容 |
|-----|------|
| 通知オブジェクト | absl::Notification |
| 送信メソッド | Notify() |
| 受信メソッド | WaitForNotification() / WaitForNotificationWithTimeout() |
| 状態確認 | HasBeenNotified() |

### 本文テンプレート

```cpp
// 送信側
absl::Notification done;
// ... 非同期処理の完了後 ...
done.Notify();

// 受信側
done.WaitForNotification();  // Notify()が呼ばれるまでブロック
```

### 添付ファイル

なし（メモリ内通信のみ）

## テンプレート変数

| 変数名 | 説明 | データ取得元 | 必須 |
|--------|------|-------------|-----|
| （なし） | absl::Notificationはデータペイロードを持たない | - | - |

## 送信トリガー・条件

### トリガー一覧

| トリガー種別 | トリガーイベント | 送信条件 | 説明 |
|------------|----------------|---------|------|
| 非同期処理完了 | Executor完了 | DirectSession.PartialRunState.executors_done | PartialRun内の全Executorが完了した時点 |
| ポーリング停止 | EventManager停止 | DeviceEventManager.polling_stopped_ | イベントマネージャのポーリングスレッド停止時 |
| テスト同期 | 各種テスト | テスト固有条件 | 非同期テストでの完了同期 |

### 送信抑止条件

| 条件 | 説明 |
|-----|------|
| 二重通知禁止 | Notify()は1回のみ呼出し可能。2回目の呼び出しはプログラムをクラッシュさせる（abslの仕様） |

## 処理フロー

### 送信フロー

```mermaid
flowchart TD
    A[Notificationオブジェクト作成] --> B[スレッド1: 非同期処理開始]
    A --> C[スレッド2: WaitForNotification]
    B --> D[非同期処理完了]
    D --> E[Notify 呼び出し]
    E --> F[スレッド2: 待機解除]
    C --> F
    F --> G[後続処理実行]
```

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

### 参照テーブル一覧

本プリミティブはデータベースを参照しない。プロセス内メモリでのスレッド間通信のみ。

### 更新テーブル一覧

なし。

## エラー処理

### エラーケース一覧

| エラー種別 | 発生条件 | 対処方法 |
|----------|---------|---------|
| 二重Notify | Notify()が2回呼ばれた場合 | プロセスがクラッシュ（abslのCHECK失敗）。プログラム設計で防止する必要がある |
| デッドロック | Notify()が呼ばれない場合 | WaitForNotificationWithTimeout()を使用してタイムアウトを設定する。DirectSessionではWaitForNotification()にタイムアウト機能を追加実装 |

### リトライ仕様

| 項目 | 内容 |
|-----|------|
| リトライ回数 | 不適用（一度限りの完了通知） |
| リトライ間隔 | - |
| リトライ対象エラー | - |

## 配信設定

### レート制限

| 項目 | 内容 |
|-----|------|
| 制限 | なし（1オブジェクトにつき1回のみ通知） |

### 配信時間帯

制限なし。プロセスのライフタイム中いつでも使用可能。

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

- プロセス内メモリでの通信のため、外部からのアクセスリスクはない
- 共有メモリ上のNotificationオブジェクトへのアクセスはスレッドセーフ（abslが保証）
- データペイロードを持たないため、情報漏洩のリスクはない

## 備考

- absl::NotificationはAbseil C++ライブラリの一部であり、TensorFlow固有の実装ではない
- TensorFlowのコアランタイム全体で広範に使用されている（テストコード含む）
- DirectSessionのWaitForNotification()はタイムアウト機能付きのラッパーを提供している（direct_session.h行309-312）
- TF2のEager実行モードでも内部的に使用されている

---

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

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

### 推奨読解順序

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

absl::Notificationの基本APIを把握する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | notification.h | `third_party/absl/synchronization/notification.h`（外部依存） | Notify(), WaitForNotification(), HasBeenNotified(), WaitForNotificationWithTimeout()の各APIの契約 |

**読解のコツ**: absl::Notificationは「一度だけ発火する」という不変条件を持つ。HasBeenNotified()がtrueになった後は決してfalseに戻らない。

#### Step 2: TensorFlowでの代表的使用パターンを理解する

DirectSessionでの使用を通じて、TensorFlow内での典型的なパターンを把握する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | direct_session.h | `tensorflow/core/common_runtime/direct_session.h` | PartialRunState構造体内のexecutors_done（行216）、WaitForNotification()メソッド（行309-312） |
| 2-2 | direct_session.cc | `tensorflow/core/common_runtime/direct_session.cc` | WaitForNotificationの実装とタイムアウト処理 |

**主要処理フロー**:
1. **行216**: `PartialRunState`内で`absl::Notification executors_done`を宣言
2. **行309-312**: タイムアウト付きWaitForNotificationのオーバーロード2種を定義

#### Step 3: DeviceEventManagerでの使用を理解する

非同期デバイスイベント管理での使用を把握する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | device_event_mgr.h | `tensorflow/core/common_runtime/device/device_event_mgr.h` | polling_stopped_メンバ変数（行143） |
| 3-2 | device_event_mgr.cc | `tensorflow/core/common_runtime/device/device_event_mgr.cc` | ポーリングスレッド停止時のNotify()呼び出し |

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

```
[DirectSession PartialRun パターン]
DirectSession::RunAsync()
    |
    +-- Executor::RunAsync(done_callback)
            |
            +-- [全executor完了]
                    +-- partial_run_state->executors_done.Notify()
                            |
DirectSession::WaitForNotification()
    +-- executors_done.WaitForNotification() / WaitForNotificationWithTimeout()
            |
            +-- [タイムアウト時] cm->StartCancel()

[DeviceEventManager パターン]
DeviceEventManager::~EventManager()
    |
    +-- polling_stopped_->WaitForNotification()
            |
EventManager::PollLoop()  [別スレッド]
    +-- [停止条件検出]
            +-- polling_stopped_->Notify()
```

### データフロー図

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

非同期処理完了 -----------> Notify() ---------------------> WaitForNotification()
(コールバック内)             (状態をnotifiedに変更)            からの復帰
                                                            (待機スレッド起床)

                            HasBeenNotified() ------------> bool (状態確認)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| notification.h | `third_party/absl/synchronization/notification.h` | 外部ライブラリ | absl::Notificationの定義 |
| direct_session.h | `tensorflow/core/common_runtime/direct_session.h` | ソース | PartialRunState.executors_done、WaitForNotification() |
| direct_session.cc | `tensorflow/core/common_runtime/direct_session.cc` | ソース | WaitForNotificationの実装 |
| device_event_mgr.h | `tensorflow/core/common_runtime/device/device_event_mgr.h` | ソース | polling_stopped_メンバ |
| device_event_mgr.cc | `tensorflow/core/common_runtime/device/device_event_mgr.cc` | ソース | ポーリング停止時の通知 |
| eager_executor.h | `tensorflow/core/common_runtime/eager/eager_executor.h` | ソース | Eager実行でのNotification使用 |
