# 通知設計書 3-Async\Condition::waitForNotificationAsync

## 概要

本ドキュメントは、HH\Lib\Async\Condition クラスの waitForNotificationAsync メソッドによる非同期通知待機機能について記載する。

### 本通知の処理概要

Async\Condition::waitForNotificationAsync メソッドは、非同期処理における条件変数（Condition Variable）パターンの受信側を実現するメカニズムである。このメソッドは、succeed または fail による通知を非同期で待機し、結果を返すか例外をスローする。

**業務上の目的・背景**：非同期プログラミングにおいて、ある処理が別の処理の完了を待つ必要がある場面が頻繁に発生する。waitForNotificationAsync は、条件変数パターンの「待機」側を提供し、通知が来るまで非同期的にブロックする機能を実現する。これにより、複数の非同期タスク間での協調動作が可能になる。

**通知の送信タイミング**：このメソッド自体は通知を送信しない。代わりに、succeed または fail メソッドからの通知を受信する役割を担う。$notifiers パラメータとして渡された Awaitable が完了する前に通知が到達することが保証されている必要がある。

**通知の受信者**：waitForNotificationAsync の呼び出し元が受信者となる。await によって非同期的に待機し、通知到達時に処理を再開する。

**通知内容の概要**：succeed の場合はジェネリック型 T の結果値を受け取り、fail の場合は例外がスローされる。

**期待されるアクション**：受信者は結果値を使用して後続の処理を継続するか、例外をキャッチしてエラーハンドリングを行う。

## 通知種別

プログラム内非同期通知（Awaitable/ConditionWaitHandle ベース・受信側）

## 送信仕様

### 基本情報

| 項目 | 内容 |
|-----|------|
| 待機方式 | 非同期（async/await） |
| タイムアウト | なし（$notifiers の完了に依存） |
| キャンセル | 不可（Hack の Awaitable は明示的なキャンセルをサポートしない） |

### 受信条件

$notifiers パラメータとして渡される Awaitable は、通知が発生する前に完了してはならない。これは、通知を発行する処理が $notifiers の実行中に行われることを保証するためである。

## 通知テンプレート

### 受信データ構造

| 項目 | 内容 |
|-----|------|
| 受信形式 | Awaitable<T> の戻り値または例外 |
| 成功時データ型 | ジェネリック型 T |
| 失敗時 | \Exception がスローされる |

### 受信データ

```hack
// 成功通知の場合
T $result = await $condition->waitForNotificationAsync($notifiers);

// 失敗通知の場合
try {
  await $condition->waitForNotificationAsync($notifiers);
} catch (\Exception $e) {
  // エラーハンドリング
}
```

### 添付ファイル

該当なし（プログラム内通知のため）

## テンプレート変数

| 変数名 | 説明 | データ取得元 | 必須 |
|--------|------|-------------|-----|
| $notifiers | 通知発生を保証するための Awaitable | 呼び出し元から引数として渡される | Yes |

## 送信トリガー・条件

### トリガー一覧

| トリガー種別 | トリガーイベント | 受信条件 | 説明 |
|------------|----------------|---------|------|
| succeed 呼び出し | 成功通知の発行 | なし | 結果値を返す |
| fail 呼び出し | 失敗通知の発行 | なし | 例外をスローする |

### 受信前提条件

| 条件 | 説明 |
|-----|------|
| $notifiers パラメータ | 通知発生を保証する Awaitable を渡す必要がある |
| 通知の一意性 | 同一インスタンスに対する通知は1回のみ |

## 処理フロー

### 受信フロー

```mermaid
flowchart TD
    A[waitForNotificationAsync 呼び出し] --> B{condition が null?}
    B -->|Yes| C[ConditionWaitHandle を作成]
    B -->|No| D[既存の condition を使用]
    C --> E[condition に ConditionWaitHandle を設定]
    D --> F[condition を await]
    E --> F
    F --> G{通知種別}
    G -->|succeed| H[結果値を返す]
    G -->|fail| I[例外をスロー]
    H --> J[終了]
    I --> J
```

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

該当なし（メモリ内での状態管理のみ）

### 参照テーブル一覧

該当なし

### 更新テーブル一覧

該当なし

## エラー処理

### エラーケース一覧

| エラー種別 | 発生条件 | 対処方法 |
|----------|---------|---------|
| 例外スロー | fail メソッドで通知された場合 | try-catch でキャッチしてハンドリング |
| $notifiers 完了前の通知なし | $notifiers が通知前に完了した場合 | $notifiers の設計を見直し |

### リトライ仕様

| 項目 | 内容 |
|-----|------|
| リトライ回数 | N/A（呼び出し元で制御） |
| リトライ間隔 | N/A |
| リトライ対象エラー | N/A |

## 配信設定

### レート制限

該当なし（プログラム内通知のため）

### 配信時間帯

制限なし

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

- 受信した結果値や例外に機密情報が含まれる可能性がある場合は、適切な取り扱いが必要
- $notifiers として渡す Awaitable の処理内容がセキュリティ上適切であることを確認

## 備考

- ConditionWaitHandle は Hack/HHVM のランタイム機能であり、このメソッドはそのラッパーとして機能する
- 通知が waitForNotificationAsync の呼び出し前に発生しても正しく動作する点が重要な特徴
- $notifiers は WaitHandle である必要があり、通知が完了するまで終了してはならない

---

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

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

### 推奨読解順序

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

Condition クラスの内部状態と、ConditionWaitHandle との関係を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | Condition.php | `src/async/Condition.php` | クラスの基本構造とプロパティ（$condition） |

**読解のコツ**: $condition プロパティが null、Awaitable<T>、ConditionWaitHandle のいずれかを保持することに注目する。

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

waitForNotificationAsync メソッドの実装を詳細に理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | Condition.php | `src/async/Condition.php` | waitForNotificationAsync メソッドの実装（66-73行目） |

**主要処理フロー**:
1. **行55-65**: メソッドのドキュメントコメント（重要な制約事項の説明）
2. **行66-68**: async メソッドの定義と $notifiers パラメータ
3. **行69-71**: condition が null の場合、ConditionWaitHandle を作成
4. **行72**: condition を await して結果を返す

#### Step 3: 関連メソッドとの連携を理解する

succeed/fail メソッドとの連携パターンを理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | Condition.php | `src/async/Condition.php` | succeed メソッド（23-36行目）との連携 |
| 3-2 | Condition.php | `src/async/Condition.php` | fail メソッド（41-52行目）との連携 |

**主要処理フロー**:
- 先に waitForNotificationAsync が呼ばれた場合: ConditionWaitHandle が作成され、succeed/fail がそれを更新
- 先に succeed/fail が呼ばれた場合: Awaitable が作成済みで、waitForNotificationAsync はそれを await

#### Step 4: テストコードで動作パターンを確認する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | ConditionTest.php | `tests/async/ConditionTest.php` | 4つのテストケース（19-63行目） |

**主要処理フロー**:
- **行19-25**: testSucceedFirst - 先に succeed、後で wait
- **行27-37**: testFailFirst - 先に fail、後で wait
- **行39-48**: testSucceedLater - 先に wait、後で succeed
- **行50-63**: testFailLater - 先に wait、後で fail

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

```
Condition::waitForNotificationAsync($notifiers)
    |
    +-- [condition が null の場合]
    |       |
    |       +-- ConditionWaitHandle::create($notifiers)
    |       |
    |       +-- $this->condition に設定
    |
    +-- await $this->condition
            |
            +-- [succeed が呼ばれた場合] 結果値を返す
            |
            +-- [fail が呼ばれた場合] 例外をスロー
```

### データフロー図

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

Awaitable<void>     waitForNotificationAsync()
$notifiers ─────────▶          |                    ┌────▶ T (成功時)
                               v                    │
                    ┌─────────────────┐             │
                    │ ConditionWait   │             │
                    │ Handle 作成     │─────await───┤
                    │ または既存使用  │             │
                    └─────────────────┘             │
                               ▲                    │
                               │                    └────▶ Exception (失敗時)
                    succeed/fail からの通知
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| Condition.php | `src/async/Condition.php` | ソース | Condition クラスの実装 |
| ConditionNode.php | `src/async/ConditionNode.php` | ソース | Condition を継承したリンクリストノード |
| ConditionTest.php | `tests/async/ConditionTest.php` | テスト | Condition クラスのユニットテスト |
| BasePoll.php | `src/async/BasePoll.php` | ソース | waitForNotificationAsync を使用する Poll 基底クラス |
| Poll.php | `src/async/Poll.php` | ソース | BasePoll を継承した具象クラス |
| KeyedPoll.php | `src/async/KeyedPoll.php` | ソース | BasePoll を継承したキー付き Poll クラス |
