# 機能設計書 114-イベントループ

## 概要

本ドキュメントは、Bunのイベントループ機能の設計を記述する。JavaScriptの非同期処理とI/O操作を効率的に管理するための中核コンポーネントである。

### 本機能の処理概要

Bunのイベントループは、uSockets（libuv互換のI/Oライブラリ）をベースに構築され、JavaScriptのPromise、タイマー、I/O操作、シグナル処理などの非同期タスクを管理する。JavaScript実行コンテキストを持つEventLoopと、JavaScript不要な軽量版MiniEventLoopの2種類を提供し、用途に応じて使い分けられる。

**業務上の目的・背景**：JavaScript/Node.jsのプログラミングモデルは非同期I/Oに基づいており、イベントループはその心臓部である。Bunは高速なJavaScriptランタイムとして、効率的なイベントループ実装により、Node.jsを上回るパフォーマンスを実現する。特に、ファイルI/O、ネットワーク通信、タイマー処理において最適化されている。

**機能の利用シーン**：
- JavaScriptの非同期関数（async/await）の実行
- setTimeout/setInterval/setImmediateの処理
- ファイルシステム操作（fs.readFile等）の非同期実行
- HTTPリクエスト/レスポンスの処理
- WebSocket通信
- シェルコマンド実行
- パッケージインストール時の並列ダウンロード
- ビルドプロセスでの並列処理

**主要な処理内容**：
1. タスクキューの管理（Task、ConcurrentTask）
2. uSocketsループとの統合
3. マイクロタスクのドレイン（Promise解決）
4. ファイルポーリング（FilePoll）
5. 並行タスクの処理（ワーカースレッドプール連携）
6. ガベージコレクション制御（GarbageCollectionController）
7. POSIXシグナル処理

**関連システム・外部連携**：
- JavaScriptCore（マイクロタスクキュー）
- uSockets/libuv（I/Oイベント）
- ワーカースレッドプール

**権限による制御**：特になし（ランタイム内部機能）

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | - | - | 本機能はランタイム内部機能であり、直接的な画面は存在しない |

## 機能種別

非同期処理管理 / I/O多重化 / タスクスケジューリング

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| allocator | std.mem.Allocator | Yes | メモリアロケータ | - |
| Task | TaggedPointerUnion | Yes | 実行するタスク | 有効なタスク型 |
| ConcurrentTask | struct | No | 並行実行タスク | - |

### 入力データソース

- JavaScriptコードからのタスク登録
- スレッドプールからの完了通知
- uSocketsからのI/Oイベント

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| - | - | タスク実行結果はコールバック/Promise経由で返却 |

### 出力先

- JavaScriptコールバック/Promise
- コンソール出力（stdout/stderr）

## 処理フロー

### 処理シーケンス

```
1. EventLoop初期化
   └─ タスクキュー初期化
   └─ uSocketsループ取得
   └─ ファイルポーリング初期化

2. tick処理（メインループ）
   └─ tickConcurrentWithCount: 並行タスクをタスクキューに移動
   └─ tickQueueWithCount: タスクキューのタスクを実行
   └─ drainMicrotasks: マイクロタスクをドレイン

3. autoTick処理（I/Oイベント待機）
   └─ uSockets loop.tick(): I/Oイベントを待機・処理

4. タスク実行
   └─ Task.Tag別のディスパッチ
   └─ runFromJSThread / runFromMainThread呼び出し
   └─ マイクロタスクドレイン
```

### フローチャート

```mermaid
flowchart TD
    A[EventLoop.tick] --> B[tickConcurrentWithCount]
    B --> C{並行タスクあり?}
    C -->|Yes| D[タスクキューに追加]
    C -->|No| E[スキップ]
    D --> F[tickQueueWithCount]
    E --> F
    F --> G{タスクあり?}
    G -->|Yes| H[タスク取得]
    G -->|No| I[終了]
    H --> J[Task.Tag判定]
    J --> K[タスク実行]
    K --> L[drainMicrotasks]
    L --> M{タスク残り?}
    M -->|Yes| H
    M -->|No| N[autoTick]
    N --> O[uSockets loop.tick]
    O --> P{イベント発生?}
    P -->|Yes| A
    P -->|No| Q{isEventLoopAlive?}
    Q -->|Yes| O
    Q -->|No| R[イベントループ終了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-001 | タスク型分類 | Task TaggedPointerUnionで90以上のタスク型をサポート | 全タスク |
| BR-002 | 自動デアロケーション | ConcurrentTask.auto_delete=trueで自動解放 | 並行タスク |
| BR-003 | マイクロタスクドレイン | 各タスク実行後にdrainMicrotasksを呼び出し | 全タスク |
| BR-004 | HotReloadTask特別処理 | HotReloadTaskはマイクロタスクドレインをスキップ | HMR時 |
| BR-005 | 終了判定 | isEventLoopAliveでイベントループ継続判定 | メインループ |
| BR-006 | MiniEventLoop | JavaScript不要な処理にはMiniEventLoopを使用 | ビルド・インストール時 |

### 計算ロジック

特になし

## データベース操作仕様

本機能はデータベースを使用しない。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| JSTerminated | 終了要求 | VM終了要求時 | イベントループ終了 |
| JSError | JavaScript例外 | タスク実行中の例外 | reportUncaughtException |
| OutOfMemory | メモリ不足 | タスクキュー拡張失敗 | エラー返却 |

### リトライ仕様

リトライは行わない。タスク実行失敗はJavaScript例外として報告。

## トランザクション仕様

本機能はトランザクションを使用しない。

## パフォーマンス要件

- タスクキューはLinearFifoで効率的なFIFO操作
- ConcurrentTaskは16バイト固定サイズ
- PackedNextPtrでポインタとフラグを1ワードにパック
- マイクロタスクドレインは各タスク実行後に即時実行

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

- POSIXシグナル処理はメインスレッドでのみ実行
- 外部からの不正なタスク注入は不可能（型安全）

## 備考

- デバッグビルドではjs_call_count_outside_tick_queueでマイクロタスクドレイン漏れを検出
- BUN_TRACK_LAST_FN_NAME環境変数で詳細デバッグ可能

---

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

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

### 推奨読解順序

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

イベントループの中核データ構造を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | Task.zig | `src/bun.js/event_loop/Task.zig` | Task TaggedPointerUnion定義 |
| 1-2 | ConcurrentTask.zig | `src/bun.js/event_loop/ConcurrentTask.zig` | ConcurrentTask構造体 |
| 1-3 | AnyEventLoop.zig | `src/bun.js/event_loop/AnyEventLoop.zig` | AnyEventLoop union定義 |

**読解のコツ**: ZigのTaggedPointerUnionは、ポインタの下位ビットを使ってタグを格納する効率的なデータ構造。

**主要処理フロー**:
- **Task.zig 4-99行目**: Task TaggedPointerUnion - 90以上のタスク型を定義
- **ConcurrentTask.zig 11-16行目**: ConcurrentTask構造体 - 16バイト固定サイズ
- **ConcurrentTask.zig 20-59行目**: PackedNextPtr - ポインタとauto_deleteフラグのパック
- **AnyEventLoop.zig 3-6行目**: AnyEventLoop union - js/miniの切り替え

#### Step 2: MiniEventLoopを理解する

JavaScript不要な軽量イベントループを理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | MiniEventLoop.zig | `src/bun.js/event_loop/MiniEventLoop.zig` | MiniEventLoop構造体 |

**主要処理フロー**:
- **1-21行目**: MiniEventLoopの目的と用途（コメント）
- **22-36行目**: MiniEventLoop構造体定義
- **114-122行目**: init関数 - uSocketsループ取得
- **153-167行目**: tickOnce - 単一tick実行
- **187-204行目**: tick - isDone条件付きループ

#### Step 3: タスク実行処理を理解する

タスクキューの処理とディスパッチを理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | Task.zig | `src/bun.js/event_loop/Task.zig` | tickQueueWithCount関数 |

**主要処理フロー**:
- **101-532行目**: tickQueueWithCount - メインタスク処理ループ
- **136-526行目**: タスク型別switch文 - 各タスクのディスパッチ
- **528行目**: drainMicrotasksWithGlobal呼び出し
- **534-542行目**: reportErrorOrTerminate - エラー処理

#### Step 4: 並行タスク処理を理解する

スレッドプールからの並行タスクを理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | ConcurrentTask.zig | `src/bun.js/event_loop/ConcurrentTask.zig` | ConcurrentTask構造体全体 |
| 4-2 | MiniEventLoop.zig | `src/bun.js/event_loop/MiniEventLoop.zig` | tickConcurrentWithCount |

**主要処理フロー**:
- **ConcurrentTask.zig 72行目**: Queue = UnboundedQueue定義
- **ConcurrentTask.zig 81-86行目**: create関数
- **MiniEventLoop.zig 129-151行目**: tickConcurrentWithCount - 並行タスクの取り込み

#### Step 5: 補助コンポーネントを理解する

GC制御やシグナル処理などの補助機能を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 5-1 | GarbageCollectionController.zig | `src/bun.js/event_loop/GarbageCollectionController.zig` | GC制御 |
| 5-2 | PosixSignalHandle.zig | `src/bun.js/event_loop/PosixSignalHandle.zig` | シグナル処理 |

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

```
VirtualMachine.tick
    │
    └─ EventLoop.tick
           │
           ├─ tickConcurrentWithCount
           │      └─ ConcurrentTaskQueue.popBatch
           │             └─ タスクキューに追加
           │
           ├─ tickQueueWithCount
           │      │
           │      └─ while (tasks.readItem())
           │             │
           │             ├─ Task.Tag判定（switch）
           │             │      ├─ FetchTasklet.onProgressUpdate
           │             │      ├─ AsyncFS.*.runFromJSThread
           │             │      ├─ ShellAsync.runFromMainThread
           │             │      ├─ AnyTask.run
           │             │      ├─ CppTask.run
           │             │      └─ ... (90+ タスク型)
           │             │
           │             └─ drainMicrotasksWithGlobal
           │
           └─ autoTick
                  └─ uSockets loop.tick

MiniEventLoop.tick
    │
    ├─ tickConcurrentWithCount
    │      └─ concurrent_tasks.popBatch
    │
    ├─ while (tasks.readItem())
    │      └─ task.run(context)
    │
    └─ loop.tick (uSockets)
```

### データフロー図

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

JavaScriptコード    ───▶  EventLoop.tick      ───▶  コールバック実行
  │                         │
  ├─ Promise.then          ├─ タスクキュー管理
  ├─ setTimeout            ├─ マイクロタスクドレイン
  ├─ fs.readFile           └─ I/Oイベント処理
  └─ fetch
                                   │
                                   ▼
                            ┌─────────────────┐
                            │ Task Queue      │
                            │ ├─ FetchTasklet │
                            │ ├─ AsyncFS.*    │
                            │ ├─ ShellAsync   │
                            │ └─ ...          │
                            └─────────────────┘
                                   │
                                   ▼
                            ┌─────────────────┐
                            │ uSockets Loop   │ ◀──▶ I/Oイベント
                            │ ├─ ファイルI/O  │
                            │ ├─ ネットワーク │
                            │ └─ タイマー     │
                            └─────────────────┘

スレッドプール      ───▶  ConcurrentTask     ───▶  メインスレッド実行
  │                         │
  └─ 完了通知              └─ Queue.push
                                   │
                                   └─ tickConcurrentWithCount
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| Task.zig | `src/bun.js/event_loop/Task.zig` | ソース | タスク型定義とディスパッチ |
| ConcurrentTask.zig | `src/bun.js/event_loop/ConcurrentTask.zig` | ソース | 並行タスク構造体 |
| AnyEventLoop.zig | `src/bun.js/event_loop/AnyEventLoop.zig` | ソース | EventLoop/MiniEventLoop統合 |
| MiniEventLoop.zig | `src/bun.js/event_loop/MiniEventLoop.zig` | ソース | 軽量イベントループ |
| AnyTask.zig | `src/bun.js/event_loop/AnyTask.zig` | ソース | 汎用タスク |
| CppTask.zig | `src/bun.js/event_loop/CppTask.zig` | ソース | C++タスク |
| ManagedTask.zig | `src/bun.js/event_loop/ManagedTask.zig` | ソース | 管理付きタスク |
| GarbageCollectionController.zig | `src/bun.js/event_loop/GarbageCollectionController.zig` | ソース | GC制御 |
| PosixSignalHandle.zig | `src/bun.js/event_loop/PosixSignalHandle.zig` | ソース | POSIXシグナル処理 |
| JSCScheduler.zig | `src/bun.js/event_loop/JSCScheduler.zig` | ソース | JSCスケジューラ |
| DeferredTaskQueue.zig | `src/bun.js/event_loop/DeferredTaskQueue.zig` | ソース | 遅延タスクキュー |
| WorkTask.zig | `src/bun.js/event_loop/WorkTask.zig` | ソース | ワークタスク |
| EventLoopHandle.zig | `src/bun.js/event_loop/EventLoopHandle.zig` | ソース | イベントループハンドル |
