# 通知設計書 8-OS\BlockingIOException

## 概要

本ドキュメントは、HH\Lib\OS\BlockingIOException クラスによるブロッキングI/O操作のエラー通知機能について記載する。

### 本通知の処理概要

OS\BlockingIOException は、非ブロッキングI/O操作において、操作がブロックする必要がある（すぐに完了できない）状況を通知する例外クラスである。EAGAIN、EALREADY、EINPROGRESS の3つの Errno 値に対応する。

**業務上の目的・背景**：非ブロッキングI/O（non-blocking I/O）を使用する際、操作がすぐに完了できない場合がある。例えば、ソケットからの読み込みでデータがまだ到着していない場合や、接続処理が進行中の場合などである。この例外は、操作を後でリトライすべきであることを示す一時的な状態を通知する。これにより、イベントループベースの非同期プログラミングパターンが実現できる。

**通知の送信タイミング**：非ブロッキングモードで設定されたファイルディスクリプタ（ソケット、パイプなど）に対する操作が、ブロッキングが必要な状態で呼び出された際にスローされる。

**通知の受信者**：非ブロッキングI/O操作を呼び出したコード（通常はイベントループやポーリング処理）が受信者となる。

**通知内容の概要**：EAGAIN（リソース一時的に利用不可）、EALREADY（操作が既に進行中）、EINPROGRESS（操作が進行中）のいずれかの Errno 値とエラーメッセージが含まれる。

**期待されるアクション**：受信者は操作を後でリトライするか、イベント通知（select/poll/epoll）を使用してリソースが利用可能になるまで待機する。

## 通知種別

例外通知（ブロッキングI/Oエラー・一時的エラー）

## 送信仕様

### 基本情報

| 項目 | 内容 |
|-----|------|
| 送信方式 | 同期（例外スロー） |
| 優先度 | N/A（例外通知のため） |
| リトライ | 推奨（一時的なエラーのため） |

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

例外は呼び出しスタックを遡って伝播し、最初の適切な catch ブロックで捕捉される。

## 通知テンプレート

### 例外の場合

| 項目 | 内容 |
|-----|------|
| 例外クラス | HH\Lib\OS\BlockingIOException |
| 親クラス | HH\Lib\OS\ErrnoException |
| 名前空間 | HH\Lib\OS |

### 例外データ構造

```hack
final class BlockingIOException extends ErrnoException {
  public function __construct(Errno $code, string $message);

  public static function _getValidErrnos(): keyset<Errno>;
}
```

### 対応 Errno 値

| Errno | 説明 | 典型的な発生状況 |
|-------|------|-----------------|
| EAGAIN | リソース一時的利用不可 | 非ブロッキング読み込みでデータなし |
| EALREADY | 操作が既に進行中 | 接続が既に開始されている |
| EINPROGRESS | 操作が進行中 | 非ブロッキング接続の開始 |

## テンプレート変数

| 変数名 | 説明 | データ取得元 | 必須 |
|--------|------|-------------|-----|
| $code | Errno 値（EAGAIN/EALREADY/EINPROGRESS） | OS からのエラーコード | Yes |
| $message | エラーメッセージ | エラー説明文字列 | Yes |

## 送信トリガー・条件

### トリガー一覧

| トリガー種別 | トリガーイベント | 送信条件 | 説明 |
|------------|----------------|---------|------|
| 読み込み操作 | 非ブロッキング read | データなし | EAGAIN |
| 書き込み操作 | 非ブロッキング write | バッファフル | EAGAIN |
| 接続操作 | 非ブロッキング connect | 接続中 | EINPROGRESS |
| 接続操作 | connect 再呼び出し | 既に接続中 | EALREADY |

### 送信抑止条件

| 条件 | 説明 |
|-----|------|
| ブロッキングモード | ブロッキングモードの場合は操作がブロックするため例外はスローされない |

## 処理フロー

### 送信フロー

```mermaid
flowchart TD
    A[非ブロッキングI/O操作] --> B{即時完了可能?}
    B -->|Yes| C[正常完了]
    B -->|No| D[errno 設定]
    D --> E{errno の種類}
    E -->|EAGAIN| F[BlockingIOException スロー]
    E -->|EALREADY| F
    E -->|EINPROGRESS| F
    F --> G[呼び出し元の catch へ]
    G --> H{リトライ戦略}
    H -->|即時リトライ| A
    H -->|イベント待機| I[select/poll で待機]
    I --> A
```

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

該当なし（OS レベルの例外通知のため）

### 参照テーブル一覧

該当なし

### 更新テーブル一覧

該当なし

## エラー処理

### エラーケース一覧

| エラー種別 | 発生条件 | 対処方法 |
|----------|---------|---------|
| EAGAIN | 読み込み/書き込み操作でリソース利用不可 | 後でリトライまたはイベント待機 |
| EALREADY | 接続操作が既に進行中 | 接続完了を待機 |
| EINPROGRESS | 接続操作が開始された（進行中） | 接続完了を待機 |

### リトライ仕様

| 項目 | 内容 |
|-----|------|
| リトライ回数 | 呼び出し側で制御（無制限も可） |
| リトライ間隔 | イベント駆動型（select/poll/epoll）または固定間隔 |
| リトライ対象エラー | EAGAIN, EALREADY, EINPROGRESS（すべて） |

## 配信設定

### レート制限

該当なし（例外通知のため）

### 配信時間帯

制限なし

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

- リトライループによるCPU過負荷を避けるため、適切なバックオフ戦略を実装する
- タイムアウトを設定し、無限ループを防止する

## 備考

- この例外は一時的なエラーを示すため、通常はリトライが適切
- EWOULDBLOCK は EAGAIN のエイリアスであり、同じ値を持つ
- 非ブロッキングI/Oを使用する際の標準的なエラーハンドリングパターンに従う

---

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

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

### 推奨読解順序

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

BlockingIOException クラスの構造と対応する Errno を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | ErrnoException.php | `src/os/ErrnoException.php` | BlockingIOException クラス（78-96行目） |
| 1-2 | Errno.php | `src/os/Errno.php` | EAGAIN, EALREADY, EINPROGRESS の定義 |

**読解のコツ**: final class として定義されており、これ以上のサブクラス化は不可能である。

#### Step 2: コンストラクタと検証ロジックを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | ErrnoException.php | `src/os/ErrnoException.php` | コンストラクタ（79-86行目） |
| 2-2 | ErrnoException.php | `src/os/ErrnoException.php` | _getValidErrnos メソッド（89-95行目） |

**主要処理フロー**:
1. **行79-86**: コンストラクタで Errno $code と $message を受け取る
2. **行80-85**: invariant で Errno が有効な値かチェック
3. **行86**: 親クラス（ErrnoException）のコンストラクタを呼び出し
4. **行89-95**: _getValidErrnos で有効な Errno の keyset を返す

#### Step 3: 親クラスとの関係を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | ErrnoException.php | `src/os/ErrnoException.php` | ErrnoException 基底クラス（52-76行目） |

**主要処理フロー**:
- BlockingIOException は ErrnoException を継承
- getErrno() メソッドで具体的な Errno 値を取得可能

#### Step 4: Errno 値の詳細を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | Errno.php | `src/os/Errno.php` | EAGAIN（49行目） |
| 4-2 | Errno.php | `src/os/Errno.php` | EWOULDBLOCK（79行目: EAGAIN のエイリアス） |
| 4-3 | Errno.php | `src/os/Errno.php` | EALREADY, EINPROGRESS（164-165行目） |

**主要処理フロー**:
- EAGAIN と EWOULDBLOCK は同じ値（79行目で EWOULDBLOCK = EAGAIN）
- これらは OS の定数から取得される

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

```
非ブロッキングI/O操作
    |
    +-- read/write/connect などのシステムコール
            |
            +-- [ブロッキングが必要な場合]
                    |
                    +-- errno = EAGAIN/EALREADY/EINPROGRESS
                    |
                    +-- BlockingIOException 生成
                    |       |
                    |       +-- invariant で Errno を検証
                    |       |
                    |       +-- ErrnoException.__construct() 呼び出し
                    |
                    +-- throw BlockingIOException
                            |
                            +-- 呼び出し元の catch ブロック
```

### データフロー図

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

非ブロッキングI/O操作
    |
    v
[操作不可状態]
    |
    v
errno (EAGAIN等) ────▶ Errno 列挙型として ────▶ BlockingIOException
                       検証                           │
                          │                           v
                          v                    throw Exception
                   C\contains チェック                │
                          │                           v
                          v                     try-catch で
                   ErrnoException               リトライ判断
                   コンストラクタ
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| ErrnoException.php | `src/os/ErrnoException.php` | ソース | BlockingIOException クラスの実装（78-96行目） |
| Errno.php | `src/os/Errno.php` | ソース | EAGAIN, EALREADY, EINPROGRESS の定義 |
