# 通知設計書 15-IPCメッセージ通知

## 概要

本ドキュメントは、Bunにおけるプロセス間通信（IPC）メッセージ通知の設計を記載する。プロセス間でシリアライズされたメッセージを送受信する機能である。

### 本通知の処理概要

IPCメッセージ通知は、親プロセスと子プロセス（Bun.spawn、child_process、cluster）間、またはBunプロセス間でメッセージを双方向に送受信する機能である。Node.jsのchild_process.fork()やclusterモジュールとの互換性を持つ。

**業務上の目的・背景**：マルチプロセスアプリケーションでは、プロセス間でのデータ共有やコマンド送信が必要となる。IPCにより、ワーカープロセスへのタスク分配、結果の収集、gracefulシャットダウンの調整などが可能になる。Node.jsとの互換性により、既存のNode.jsアプリケーションをBunで実行できる。

**通知の送信タイミング**：`process.send()`または`subprocess.send()`が呼び出された時点で、シリアライズされたメッセージがソケット経由で送信される。

**通知の受信者**：接続されたIPCソケットの反対側のプロセス。親→子、子→親の双方向通信が可能。

**通知内容の概要**：JSON形式（jsonモード）またはSerializedScriptValue形式（advancedモード）でシリアライズされたJavaScript値。オブジェクト、配列、文字列、数値、booleanなどを送信可能。

**期待されるアクション**：受信プロセスの`message`イベントハンドラが発火し、デシリアライズされたメッセージを処理する。

## 通知種別

プロセス間通信（IPC Socket）

## 送信仕様

### 基本情報

| 項目 | 内容 |
|-----|------|
| 送信方式 | 非同期 |
| 優先度 | 高 |
| リトライ | ハンドル送信時のみ（最大3回） |

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

IPCソケットが確立されている相手プロセスに対して直接送信。親プロセスから子プロセス、または子プロセスから親プロセス。

## 通知テンプレート

### IPCメッセージの場合

| 項目 | 内容 |
|-----|------|
| プロトコル | UNIXドメインソケット（POSIX）/ Named Pipe（Windows） |
| シリアライズ形式 | json または advanced |
| フォーマット | モードにより異なる |

### JSONモードメッセージ構造

```
{JSONシリアライズされたデータ}\n
```

### Advancedモードメッセージ構造

```
[1バイト: メッセージタイプ]
  - 1: Version
  - 2: SerializedMessage
  - 3: SerializedInternalMessage
[4バイト: メッセージ長 (u32, little-endian)]
[可変長: SerializedScriptValueデータ]
```

### 添付ファイル

なし（ただしファイルディスクリプタのハンドル送信は可能）

## テンプレート変数

| 変数名 | 説明 | データ取得元 | 必須 |
|--------|------|-------------|-----|
| message | 送信するJavaScript値 | process.send()の引数 | Yes |
| handle | 送信するハンドル（サーバー/ソケット） | process.send()の引数 | No |
| callback | 送信完了コールバック | process.send()の引数 | No |

## 送信トリガー・条件

### トリガー一覧

| トリガー種別 | トリガーイベント | 送信条件 | 説明 |
|------------|----------------|---------|------|
| API呼び出し | process.send() | IPCチャネルが開いている | 子プロセスから親へ送信 |
| API呼び出し | subprocess.send() | IPCチャネルが開いている | 親プロセスから子へ送信 |

### 送信抑止条件

| 条件 | 説明 |
|-----|------|
| IPCチャネル閉鎖 | チャネルが閉じている場合はERR_IPC_CHANNEL_CLOSEDエラー |
| シリアライズ不可 | シリアライズできない値の場合はエラー |
| プロセス終了 | 対象プロセスが終了している場合 |

## 処理フロー

### 送信フロー

```mermaid
flowchart TD
    A[process.send/subprocess.send呼び出し] --> B{IPCチャネル開いている?}
    B -->|No| C[ERR_IPC_CHANNEL_CLOSEDエラー]
    B -->|Yes| D{messageが有効な型?}
    D -->|No| E[TypeError]
    D -->|Yes| F{handleあり?}
    F -->|Yes| G[ハンドルをシリアライズ]
    F -->|No| H[メッセージをシリアライズ]
    G --> H
    H --> I{シリアライズ成功?}
    I -->|No| J[SerializationFailedエラー]
    I -->|Yes| K[SendQueueに追加]
    K --> L[ソケットに書き込み]
    L --> M{書き込み成功?}
    M -->|Yes| N[コールバック呼び出し/true返却]
    M -->|No| O[バックオフ/false返却]
```

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

### 参照テーブル一覧

本通知はデータベースを使用しない。

| データ構造 | 用途 | 備考 |
|-----------|------|------|
| SendQueue | メッセージキュー | 送信待ちメッセージを管理 |
| IncomingBuffer | 受信バッファ | JSONまたはadvancedモード用 |
| Handle | ファイルディスクリプタハンドル | FD + JSValue |

## エラー処理

### エラーケース一覧

| エラー種別 | 発生条件 | 対処方法 |
|----------|---------|---------|
| ERR_IPC_CHANNEL_CLOSED | IPCチャネルが閉じている | エラーをスロー/コールバックに渡す |
| TypeError | メッセージ型が不正 | エラーをスロー |
| SerializationFailed | シリアライズ失敗 | エラーをスロー |
| ハンドル送信失敗 | ACK/NACK受信 | 最大3回リトライ |

### リトライ仕様

| 項目 | 内容 |
|-----|------|
| リトライ回数 | 3（ハンドル送信時のみ） |
| リトライ間隔 | 即時 |
| リトライ対象エラー | NACK受信時 |

## 配信設定

### レート制限

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

### 配信時間帯

プロセス稼働中は常時送信可能

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

- IPCチャネルはプロセス間の直接通信のため、外部からのアクセスは不可
- ファイルディスクリプタの送信は信頼できるプロセス間でのみ使用
- SerializedScriptValueは`forCrossProcessTransfer`オプションで安全なシリアライズを行う

## 備考

- Node.jsのchild_process.fork()やclusterモジュールとの互換性あり
- jsonモードはNode.js互換、advancedモードはBun専用（より効率的）
- ハンドル送信にはACK/NACKプロトコルを使用

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | ipc.zig | `src/bun.js/ipc.zig` | Mode列挙型（json/advanced）、DecodedIPCMessage union型 |
| 1-2 | ipc.zig | `src/bun.js/ipc.zig` | SendQueue構造体、SendHandle構造体 |
| 1-3 | ipc.zig | `src/bun.js/ipc.zig` | IncomingBuffer（json用JSONLineBuffer/advanced用ByteList） |

**読解のコツ**: jsonモードとadvancedモードで処理が分岐する。advanced構造体内のヘッダー長（5バイト）とメッセージタイプを理解することが重要。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | ipc.zig | `src/bun.js/ipc.zig` | doSend関数（968-1043行目） |
| 2-2 | ipc.zig | `src/bun.js/ipc.zig` | serializeAndSend関数（793-808行目） |

**主要処理フロー**:
1. **968-1000行目**: 引数のバリデーションとハンドル処理
2. **1001-1032行目**: ハンドルのシリアライズ
3. **1033行目**: serializeAndSend呼び出し

#### Step 3: シリアライズ処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | ipc.zig | `src/bun.js/ipc.zig` | advanced.serialize関数（142-165行目） |
| 3-2 | ipc.zig | `src/bun.js/ipc.zig` | json.serialize関数（257-284行目） |

**主要処理フロー**:
- **advanced.serialize**: SerializedScriptValue使用、バイナリ形式
- **json.serialize**: JSON.stringify使用、改行区切り

#### Step 4: 受信処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | ipc.zig | `src/bun.js/ipc.zig` | decodeIPCMessage関数（289-294行目） |
| 4-2 | ipc.zig | `src/bun.js/ipc.zig` | handleIPCMessage関数（1064-1159行目） |

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

```
process.send() / subprocess.send()
    │
    ├─ doSend()
    │      │
    │      ├─ 引数バリデーション
    │      │      ├─ IPCチャネル接続確認
    │      │      └─ メッセージ型確認
    │      │
    │      ├─ ハンドル処理（オプション）
    │      │      └─ ipcSerialize() → IPC.cpp経由
    │      │
    │      └─ serializeAndSend()
    │             │
    │             ├─ startMessage()
    │             │      └─ SendQueueにエントリ追加
    │             │
    │             ├─ serialize()
    │             │      ├─ json.serialize() [JSONモード]
    │             │      │      └─ JSON.stringify + 改行
    │             │      │
    │             │      └─ advanced.serialize() [advancedモード]
    │             │             └─ SerializedScriptValue
    │             │
    │             └─ continueSend()
    │                    └─ _write() → ソケット書き込み
    │
    └─ 受信側
           │
           └─ onData2()
                  │
                  ├─ decodeIPCMessage()
                  │      ├─ json.decodeIPCMessage()
                  │      └─ advanced.decodeIPCMessage()
                  │
                  └─ handleIPCMessage()
                         └─ messageイベント発火
```

### データフロー図

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

送信プロセス             IPC層                        受信プロセス
process.send() ───▶ serialize() ───▶ ソケット ───▶ onData2() ───▶ messageイベント
    │                    │               │              │              │
    │                    │               │              │              │
    └─ JSValue           └─ シリアライズ  └─ バイト列    └─ デシリアライズ └─ JSValue
       + ハンドル(opt)      (json/adv)                      + 検証
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| ipc.zig | `src/bun.js/ipc.zig` | ソース | IPCメイン実装、送受信ロジック |
| IPC.cpp | `src/bun.js/bindings/IPC.cpp` | ソース | C++バインディング、シリアライズヘルパー |
| subprocess.zig | `src/bun.js/api/bun/subprocess.zig` | ソース | Bun.spawn IPC統合 |
| child_process.ts | `src/js/node/child_process.ts` | ソース | Node.js互換child_processモジュール |
| Ipc.ts | `src/js/builtins/Ipc.ts` | ソース | JavaScript側IPCビルトイン |
| node_cluster_binding.zig | `src/bun.js/node/node_cluster_binding.zig` | ソース | clusterモジュール統合 |
