# 通知設計書 1-Async\Condition::succeed

## 概要

本ドキュメントは、HH\Lib\Async\Condition クラスの succeed メソッドによる非同期条件変数への成功通知機能について記載する。

### 本通知の処理概要

Async\Condition::succeed メソッドは、非同期処理における条件変数（Condition Variable）パターンを実現するための成功通知メカニズムである。このメソッドは、待機中の非同期処理に対して処理の完了と結果値を通知する。

**業務上の目的・背景**：非同期プログラミングにおいて、複数の非同期タスク間で結果を受け渡す必要がある場面が頻繁に発生する。従来の ConditionWaitHandle は、通知イベントが待機開始前に発生すると正しく動作しない問題があった。Async\Condition クラスはこの問題を解決し、通知イベントが待機開始前に発生しても正しく結果を受け取れるラッパーを提供する。

**通知の送信タイミング**：succeed メソッドは、非同期処理が正常に完了し結果値が確定した時点で呼び出される。呼び出し元が任意のタイミングで明示的に呼び出すことで通知が発生する。

**通知の受信者**：同一の Condition インスタンスに対して waitForNotificationAsync を呼び出している非同期処理が受信者となる。1つの Condition インスタンスに対しては1回のみ通知可能である。

**通知内容の概要**：ジェネリック型 T で指定された結果値が通知内容となる。この値は waitForNotificationAsync の戻り値として受信者に渡される。

**期待されるアクション**：受信者は waitForNotificationAsync から結果値を受け取り、後続の処理を継続する。通知を受け取った時点で await が解除され、結果値を使用した処理が実行可能になる。

## 通知種別

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

## 送信仕様

### 基本情報

| 項目 | 内容 |
|-----|------|
| 送信方式 | 同期（メソッド呼び出し時に即座に状態変更） |
| 優先度 | N/A（プログラム内通知のため） |
| リトライ | 無（1回のみ通知可能） |

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

送信先は同一 Condition インスタンスを参照する waitForNotificationAsync の呼び出し元である。インスタンスベースの1対1通知のため、明示的な送信先決定ロジックは存在しない。

## 通知テンプレート

### プログラム通知の場合

| 項目 | 内容 |
|-----|------|
| 通知形式 | Awaitable の完了 |
| データ型 | ジェネリック型 T |
| 通知方法 | ConditionWaitHandle::succeed または async ブロックによる即時完了 |

### 通知データ構造

```hack
// 成功通知時のデータ
T $result  // ジェネリック型の結果値
```

### 添付ファイル

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

## テンプレート変数

| 変数名 | 説明 | データ取得元 | 必須 |
|--------|------|-------------|-----|
| $result | 通知する結果値 | 呼び出し元から引数として渡される | Yes |

## 送信トリガー・条件

### トリガー一覧

| トリガー種別 | トリガーイベント | 送信条件 | 説明 |
|------------|----------------|---------|------|
| API呼び出し | succeed($result) メソッド呼び出し | なし | 呼び出し元が明示的に成功を通知 |

### 送信抑止条件

| 条件 | 説明 |
|-----|------|
| 二重通知 | 同一インスタンスに対して既に succeed または fail が呼び出されている場合、invariant 違反でエラー |

## 処理フロー

### 送信フロー

```mermaid
flowchart TD
    A[succeed メソッド呼び出し] --> B{condition が null?}
    B -->|Yes| C[async ブロックで即時完了 Awaitable を作成]
    B -->|No| D{ConditionWaitHandle?}
    D -->|Yes| E[ConditionWaitHandle::succeed を呼び出し]
    D -->|No| F[invariant 違反エラー]
    C --> G[condition に Awaitable を設定]
    E --> H[待機中の処理に結果を通知]
    G --> I[終了]
    H --> I
    F --> I
```

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

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

### 参照テーブル一覧

該当なし

### 更新テーブル一覧

該当なし

## エラー処理

### エラーケース一覧

| エラー種別 | 発生条件 | 対処方法 |
|----------|---------|---------|
| invariant 違反 | 同一インスタンスに2回以上 succeed/fail を呼び出した場合 | プログラム設計を見直し、1回のみ通知するよう修正 |
| 型エラー | 結果値の型が T と一致しない場合 | コンパイル時に検出される |

### リトライ仕様

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

## 配信設定

### レート制限

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

### 配信時間帯

制限なし

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

- 結果値に機密情報を含む場合は、受信側での適切な取り扱いが必要
- Condition インスタンスへの参照を持つコードのみが通知・待機可能

## 備考

- HH\Lib\Async\Condition は ConditionWaitHandle のラッパーとして機能する
- 通知が待機開始前に発生しても正しく動作する点が ConditionWaitHandle との主な違い
- このクラスは HSL (Hack Standard Library) の一部として提供される

---

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

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

### 推奨読解順序

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

Condition クラスの内部状態と、通知に関わるデータ構造を理解する。

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

**読解のコツ**: Hack言語のジェネリクス構文（`<T>`）と nullable 型（`?Awaitable<T>`）に注意する。

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

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

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

**主要処理フロー**:
1. **行23-36**: succeed メソッドの定義
2. **行24**: condition プロパティが null かチェック
3. **行25-27**: null の場合、async ブロックで即時完了 Awaitable を作成
4. **行29-31**: null でない場合、ConditionWaitHandle かどうかを invariant でチェック
5. **行34**: ConditionWaitHandle の succeed を呼び出し

#### Step 3: 関連クラスを理解する

waitForNotificationAsync との連携を理解する。

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

**主要処理フロー**:
- **行66-73**: waitForNotificationAsync の実装
- **行69-71**: condition が null の場合に ConditionWaitHandle を作成
- **行72**: condition を await して結果を返す

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | ConditionTest.php | `tests/async/ConditionTest.php` | succeed の使用例（19-25行目、39-48行目） |

**主要処理フロー**:
- **行19-25**: testSucceedFirst - 先に succeed を呼び出すパターン
- **行39-48**: testSucceedLater - 後から succeed を呼び出すパターン

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

```
Condition::succeed($result)
    |
    +-- [condition が null の場合]
    |       |
    |       +-- async { return $result; } を作成
    |       |
    |       +-- $this->condition に設定
    |
    +-- [condition が ConditionWaitHandle の場合]
            |
            +-- ConditionWaitHandle::succeed($result)
                    |
                    +-- 待機中の waitForNotificationAsync を解除
```

### データフロー図

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

$result (T型) ───────▶ Condition::succeed() ───────▶ Awaitable<T> 完了
                              |
                              v
                    ┌─────────────────┐
                    │  $condition     │
                    │  プロパティ更新  │
                    └─────────────────┘
                              |
                              v
                    waitForNotificationAsync
                    の await が解除され
                    $result が返却される
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| 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` | ソース | ConditionNode を使用する Poll の基底クラス |
