# 機能設計書 25-timers

## 概要

本ドキュメントは、Node.jsのtimersモジュールの機能設計について記述する。timersモジュールは、一定時間後にコールバックを実行するタイマー機能を提供し、Node.jsのイベントループと密接に連携して動作する。

### 本機能の処理概要

**業務上の目的・背景**：timersモジュールは、時間ベースの非同期処理を実現するための基盤機能を提供する。一定時間後の処理実行（setTimeout）、定期的な処理実行（setInterval）、I/Oイベント処理後の即時実行（setImmediate）など、様々な時間制御パターンをサポートする。これらはNode.jsの非同期プログラミングモデルの根幹を成す。

**機能の利用シーン**：
- 一定時間後に処理を実行する際（setTimeout）
- 定期的に処理を繰り返し実行する際（setInterval）
- 現在のI/Oサイクル完了後に処理を実行する際（setImmediate）
- スケジュールされたタイマーをキャンセルする際
- タイマーをPromiseベースで使用する際（timers/promises）

**主要な処理内容**：
1. `setTimeout(callback, delay, ...args)` - 指定ミリ秒後にコールバックを実行
2. `clearTimeout(timer)` - setTimeoutをキャンセル
3. `setInterval(callback, delay, ...args)` - 指定ミリ秒ごとにコールバックを繰り返し実行
4. `clearInterval(timer)` - setIntervalをキャンセル
5. `setImmediate(callback, ...args)` - I/Oイベント後にコールバックを実行
6. `clearImmediate(immediate)` - setImmediateをキャンセル
7. `timers.promises` - Promiseベースのタイマー関数

**関連システム・外部連携**：
- internalBinding('timers') - ネイティブタイマー実装
- internal/timers - Timeout/Immediateクラス定義
- async_hooks - 非同期リソース追跡

**権限による制御**：特になし。すべての機能は任意のユーザーコードから利用可能。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | - | - | 本モジュールはAPI機能であり、関連する画面はありません |

## 機能種別

タイマー制御 / 非同期処理スケジューリング

## 入力仕様

### 入力パラメータ

#### setTimeout

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| callback | Function | Yes | 実行するコールバック | validateFunction |
| delay | number | No | 遅延ミリ秒（デフォルト0） | - |
| ...args | any[] | No | コールバックに渡す引数 | - |

#### clearTimeout

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| timer | Timeout \| string \| number | No | キャンセルするタイマー | - |

#### setInterval

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| callback | Function | Yes | 実行するコールバック | validateFunction |
| repeat | number | No | 繰り返し間隔ミリ秒 | - |
| ...args | any[] | No | コールバックに渡す引数 | - |

#### clearInterval

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| timer | Timeout \| string \| number | No | キャンセルするタイマー | - |

#### setImmediate

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| callback | Function | Yes | 実行するコールバック | validateFunction |
| ...args | any[] | No | コールバックに渡す引数 | - |

#### clearImmediate

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| immediate | Immediate | No | キャンセルするImmediate | - |

### 入力データソース

プログラムコードからの直接呼び出し。

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| setTimeout戻り値 | Timeout | タイマーオブジェクト（キャンセル用） |
| setInterval戻り値 | Timeout | タイマーオブジェクト（キャンセル用） |
| setImmediate戻り値 | Immediate | Immediateオブジェクト（キャンセル用） |

### 出力先

呼び出し元への戻り値として返却。タイマー発火時にコールバックが実行される。

## 処理フロー

### 処理シーケンス

```
1. タイマー登録（setTimeout/setInterval/setImmediate）
   └─ Timeout/Immediateインスタンスを生成
2. 内部リストへ挿入
   └─ timerListMap/immediateQueueに追加
3. イベントループ待機
   └─ 指定時間/タイミングで発火
4. コールバック実行
   └─ 引数付きでコールバックを呼び出し
5. クリーンアップ（setTimeoutの場合）
   └─ 内部リストから削除
```

### フローチャート

```mermaid
flowchart TD
    A[タイマー関数呼び出し] --> B{関数タイプ}
    B -->|setTimeout| C[Timeoutインスタンス生成]
    B -->|setInterval| D[Timeout（repeat=true）生成]
    B -->|setImmediate| E[Immediateインスタンス生成]
    C --> F[timerListMapに挿入]
    D --> F
    E --> G[immediateQueueに追加]
    F --> H[タイマーオブジェクト返却]
    G --> I[Immediateオブジェクト返却]
    H --> J[イベントループで待機]
    I --> K[I/O完了後に実行]
    J --> L[時間経過後コールバック実行]
    K --> M[コールバック実行]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-001 | delay範囲制限 | delayは整数に切り捨てられる | setTimeout/setInterval |
| BR-002 | clearTimeout/Interval互換 | clearTimeoutとclearIntervalは互換性あり | HTML Living Standard準拠 |
| BR-003 | プリミティブ変換 | Timeoutはプリミティブ（数値ID）に変換可能 | SymbolToPrimitive |
| BR-004 | Disposable対応 | Timeout/ImmediateはSymbolDispose対応 | using文で利用可能 |

### 計算ロジック

#### setTimeout処理（115-120行目）
1. コールバック関数のバリデーション
2. Timeoutインスタンスの生成（repeat=false）
3. insert関数で内部リストに追加
4. Timeoutオブジェクトを返却

#### unenroll処理（71-104行目）
1. タイマーの破棄フラグ設定
2. knownTimersById からの削除（プリミティブ変換時）
3. emitDestroyによるasync_hooks通知
4. リンクリストからの削除
5. 参照カウントの減少

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

### 操作別データベース影響一覧

本モジュールはデータベース操作を行わない。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| ERR_INVALID_ARG_TYPE | TypeError | callbackが関数でない | 関数を渡す |

### リトライ仕様

リトライ処理は行わない。

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

トランザクション処理は行わない。

## パフォーマンス要件

- 優先度キュー（timerListQueue）による効率的なタイマー管理
- 遅延ロードによるtimers/promisesの初期化コスト削減
- refed/unrefedリストの分離管理

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

特になし。

## 備考

- Timeout.prototype.ref() / unref()でイベントループへの影響を制御可能
- timers/promisesモジュールでPromiseベースのAPIを提供
- util.promisifyによるPromise化もサポート（customPromisify）

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | internal/timers.js | `lib/internal/timers.js` | Timeout/Immediateクラス定義 |

**読解のコツ**: Timeoutクラスの_idleTimeout、_onTimeout、_repeat等のプロパティを理解する。timerListMap（タイムアウト値→リスト）とtimerListQueue（優先度キュー）の関係を把握する。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | timers.js | `lib/timers.js` | module.exports（250-257行目） |

**主要処理フロー**:
1. **250-257行目**: 6つの主要関数のエクスポート
2. **259-268行目**: timers.promisesの遅延ロード定義

#### Step 3: setTimeout/clearTimeout実装を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | timers.js | `lib/timers.js` | setTimeout関数（115-120行目） |
| 3-2 | timers.js | `lib/timers.js` | clearTimeout関数（136-149行目） |

**主要処理フロー**:
- **116行目**: validateFunctionでコールバック検証
- **117行目**: Timeoutインスタンス生成（repeat=false, refed=true）
- **118行目**: insert関数でタイマーリストに挿入
- **137-141行目**: clearTimeoutの_onTimeout経由のクリア
- **142-148行目**: プリミティブID経由のクリア

#### Step 4: setImmediate/clearImmediate実装を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | timers.js | `lib/timers.js` | setImmediate関数（207-210行目） |
| 4-2 | timers.js | `lib/timers.js` | clearImmediate関数（226-244行目） |

**主要処理フロー**:
- **208行目**: validateFunctionでコールバック検証
- **209行目**: Immediateインスタンス生成
- **227-228行目**: 既に破棄済みの場合は早期リターン
- **230-237行目**: 参照カウントとtoggleImmediateRef処理

#### Step 5: unenroll処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 5-1 | timers.js | `lib/timers.js` | unenroll関数（71-104行目） |

**主要処理フロー**:
- **72-73行目**: 既に破棄済みの場合は早期リターン
- **75行目**: _destroyedフラグを設定
- **77-78行目**: プリミティブ変換していた場合はknownTimersByIdから削除
- **80行目**: emitDestroyでasync_hooks通知
- **82行目**: リンクリストから削除
- **89-99行目**: refedタイマーの場合、空リスト削除と参照カウント減少

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

```
lib/timers.js
    │
    ├─ setTimeout() [115-120行目]
    │      ├─ validateFunction() [116行目]
    │      ├─ new Timeout() [117行目]
    │      └─ insert() [118行目]
    │
    ├─ clearTimeout() [136-149行目]
    │      └─ unenroll() [71-104行目]
    │              └─ emitDestroy() [80行目]
    │
    ├─ setInterval() [159-164行目]
    │      └─ (setTimeoutと同様、repeat=true)
    │
    ├─ clearInterval() [171-176行目]
    │      └─ clearTimeout() [175行目]
    │
    ├─ setImmediate() [207-210行目]
    │      └─ new Immediate() [209行目]
    │
    ├─ clearImmediate() [226-244行目]
    │      └─ emitDestroy() [239行目]
    │
    └─ timers.promises (遅延ロード)
           └─ require('timers/promises')
```

### データフロー図

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

callback+delay ───▶ setTimeout ───▶ Timeoutオブジェクト
                                        │
                                        ▼
                                  timerListMapに挿入
                                        │
                                        ▼
                                  イベントループ待機
                                        │
                                        ▼
                                  コールバック実行

callback+args ───▶ setImmediate ───▶ Immediateオブジェクト
                                        │
                                        ▼
                                  immediateQueueに追加
                                        │
                                        ▼
                                  I/O完了後にコールバック実行
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| timers.js | `lib/timers.js` | ソース | メインモジュール |
| internal/timers.js | `lib/internal/timers.js` | ソース | Timeout/Immediateクラス |
| internal/linkedlist.js | `lib/internal/linkedlist.js` | ソース | リンクリスト操作 |
| timers/promises.js | `lib/timers/promises.js` | ソース | Promiseベースのタイマー |
| internal/async_hooks.js | `lib/internal/async_hooks.js` | ソース | 非同期追跡 |
| internal/validators.js | `lib/internal/validators.js` | ソース | バリデーション |
