# 機能設計書 83-asyncfutures

## 概要

本ドキュメントは、Nim標準ライブラリのasyncfuturesモジュールに関する機能設計書である。非同期プログラミングの基盤となるFuture/Promise型を実装し、非同期操作の結果管理とコールバック処理を提供する。

### 本機能の処理概要

asyncfuturesモジュールは、Nimの非同期プログラミングにおける中核的なデータ型であるFuture[T]型を定義する。Futureは「将来のある時点で利用可能になる値」を表現する型であり、JavaScriptのPromise、C#のTask、RustのFutureに相当する概念である。

**業務上の目的・背景**：非同期プログラミングでは、I/O操作やネットワーク通信の完了を待つ間、他の処理を並行して実行することでリソースを効率的に活用する。Futureは非同期操作の結果を「約束」として保持し、完了時にコールバックを呼び出すことで、複雑な非同期フローを構造化された方法で管理可能にする。

**機能の利用シーン**：asyncdispatchモジュールと連携して使用され、全ての非同期操作（ネットワークI/O、ファイルI/O、タイマー等）の結果をFutureとして返す。開発者はawaitキーワードまたはコールバックを使ってFutureの完了を待機する。

**主要な処理内容**：
1. Future[T]型の生成と管理（newFuture関数）
2. Futureの完了処理（complete関数）
3. Futureのエラー処理（fail関数）
4. コールバックの登録と実行（addCallback関数）
5. 複数Futureの合成処理（and, or, all演算子）

**関連システム・外部連携**：asyncdispatch、asyncmacro、asyncstreams、asyncfile等の非同期モジュールから利用される。

**権限による制御**：特になし。

## 関連画面

該当なし（ライブラリモジュールのため画面との直接的な関連はない）

## 機能種別

データ構造 / 非同期処理基盤

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| fromProc | string | No | デバッグ用のプロシージャ名 | デフォルト"unspecified" |
| val | T | Yes | Futureに設定する値 | 型Tに応じた値 |
| error | ref Exception | Yes | fail時の例外オブジェクト | 非nil |
| cb | proc() | Yes | コールバック関数 | 非nil |

### 入力データソース

非同期操作からの完了通知

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| Future[T] | ref object | 非同期操作の結果を保持するオブジェクト |
| FutureVar[T] | distinct Future[T] | 再利用可能なFuture |
| FutureBase | ref object | 型なしの基底Future |

### 出力先

コールバック関数への通知 / await式への値伝播

## 処理フロー

### 処理シーケンス

```
1. Future生成
   └─ newFuture[T](fromProc)
      ├─ メモリ割り当て
      ├─ finished = false
      ├─ [デバッグ時] スタックトレース保存
      └─ [futureLogging時] logFutureStart呼び出し

2. コールバック登録
   └─ addCallback(cb)
      ├─ finished=true → callSoon(cb)
      └─ finished=false → callbacks.add(cb)

3. Future完了
   └─ complete(val)
      ├─ checkFinished()で二重完了チェック
      ├─ value = val
      ├─ finished = true
      ├─ callbacks.call()
      └─ [futureLogging時] logFutureFinish呼び出し

4. 結果取得
   └─ read()
      ├─ finished=true & error=nil → result = value
      ├─ finished=true & error!=nil → raise error
      └─ finished=false → raise ValueError
```

### フローチャート

```mermaid
flowchart TD
    A[newFuture] --> B[Future生成]
    B --> C{コールバック登録?}
    C -->|Yes| D[addCallback]
    D --> E{finished?}
    E -->|Yes| F[callSoon cb]
    E -->|No| G[リストに追加]

    H[非同期操作完了] --> I{成功?}
    I -->|Yes| J[complete val]
    I -->|No| K[fail error]

    J --> L[checkFinished]
    K --> L
    L --> M{二重完了?}
    M -->|Yes| N[FutureError]
    M -->|No| O[finished=true]
    O --> P[callbacks.call]

    Q[read] --> R{finished?}
    R -->|No| S[ValueError]
    R -->|Yes| T{error?}
    T -->|Yes| U[raise error]
    T -->|No| V[return value]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-83-01 | 一度きりの完了 | Futureは一度だけcomplete/failできる | 全てのFuture |
| BR-83-02 | 完了済みへのコールバック | 完了済みFutureへのコールバックは即座にcallSoon | addCallback呼び出し時 |
| BR-83-03 | 読み込み制約 | 未完了Futureからのreadは例外 | read呼び出し時 |
| BR-83-04 | エラー伝播 | fail時のエラーはreadで再raise | read呼び出し時 |

### 計算ロジック

**コールバック実行**（call関数）:
- CallbackListをリンクリストとして走査
- 各コールバックをcallSoonで登録（即時実行ではなく遅延実行）
- 実行後にリストをnilにしてGCに回収させる

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

該当なし

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| FutureError | 二重完了 | 完了済みFutureを再度complete/fail | デバッグモードで検出 |
| ValueError | 未完了read | 未完了Futureからread | awaitまたはfinished確認 |
| ValueError | エラーなしreadError | error=nilのFutureからreadError | failedでエラー有無確認 |

### リトライ仕様

該当なし（Futureは一度きりの完了）

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

該当なし

## パフォーマンス要件

- Future生成: O(1)
- コールバック追加: O(1) amortized
- コールバック実行: O(n) where n = コールバック数
- メモリ使用量: 約80-120バイト/Future（デバッグ情報含む）

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

- スタックトレース情報はリリースビルドでは省略可能
- FutureLoggingはデバッグ目的でのみ使用

## 備考

- FutureVar[T]は再利用可能なFutureで、メモリ割り当てを節約
- -d:futureLoggingでペンディングFutureの追跡が可能
- NimAsyncContinueSuffixは内部使用のための定数

---

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

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

### 推奨読解順序

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

まず、Future型の内部構造を理解することが重要。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | asyncfutures.nim | `lib/pure/asyncfutures.nim` | CallbackFunc/CallbackList型（20-24行目） |
| 1-2 | asyncfutures.nim | `lib/pure/asyncfutures.nim` | FutureBase型（26-35行目） |
| 1-3 | asyncfutures.nim | `lib/pure/asyncfutures.nim` | Future[T]型（37-38行目） |
| 1-4 | asyncfutures.nim | `lib/pure/asyncfutures.nim` | FutureVar[T]型（40行目） |
| 1-5 | asyncfutures.nim | `lib/pure/asyncfutures.nim` | FutureError型（42-43行目） |

**読解のコツ**:
- CallbackListは単方向リンクリストとして実装されている
- FutureBaseは型パラメータを持たない基底型で、FutureBase全体を扱う関数で使用
- Future[T]はFutureBaseを継承し、valueフィールドで型付き結果を保持

#### Step 2: Future生成フローを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | asyncfutures.nim | `lib/pure/asyncfutures.nim` | setupFutureBaseテンプレート（112-119行目） |
| 2-2 | asyncfutures.nim | `lib/pure/asyncfutures.nim` | newFuture関数（121-127行目） |
| 2-3 | asyncfutures.nim | `lib/pure/asyncfutures.nim` | newFutureVar関数（129-137行目） |

**主要処理フロー**:
- **112-119行目**: new(result)でメモリ確保、finished=false、デバッグ情報設定
- **121-127行目**: setupFutureBaseテンプレートを呼び出し、futureLogging時はログ記録

#### Step 3: コールバック管理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | asyncfutures.nim | `lib/pure/asyncfutures.nim` | callSoonプロシージャ関連（90-110行目） |
| 3-2 | asyncfutures.nim | `lib/pure/asyncfutures.nim` | call関数（165-177行目） |
| 3-3 | asyncfutures.nim | `lib/pure/asyncfutures.nim` | add関数（179-194行目） |
| 3-4 | asyncfutures.nim | `lib/pure/asyncfutures.nim` | addCallback関数（249-267行目） |
| 3-5 | asyncfutures.nim | `lib/pure/asyncfutures.nim` | callback=関数（269-283行目） |

**主要処理フロー**:
- **100-110行目**: callSoonは即時実行ではなくディスパッチャに登録
- **165-177行目**: CallbackListを走査し、各コールバックをcallSoonで登録
- **249-257行目**: 完了済みならcallSoon、未完了ならリストに追加

#### Step 4: 完了処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | asyncfutures.nim | `lib/pure/asyncfutures.nim` | checkFinished関数（144-163行目） |
| 4-2 | asyncfutures.nim | `lib/pure/asyncfutures.nim` | completeImpl関数（196-204行目） |
| 4-3 | asyncfutures.nim | `lib/pure/asyncfutures.nim` | complete関数群（206-232行目） |
| 4-4 | asyncfutures.nim | `lib/pure/asyncfutures.nim` | fail関数（234-243行目） |

**主要処理フロー**:
- **144-163行目**: デバッグモードで二重完了をチェックし、詳細エラーメッセージ生成
- **196-204行目**: 値設定、finished=true、コールバック呼び出し
- **234-243行目**: error設定、スタックトレース保存、コールバック呼び出し

#### Step 5: 結果取得と合成演算子を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 5-1 | asyncfutures.nim | `lib/pure/asyncfutures.nim` | readテンプレート（362-376行目） |
| 5-2 | asyncfutures.nim | `lib/pure/asyncfutures.nim` | read関数（377-385行目） |
| 5-3 | asyncfutures.nim | `lib/pure/asyncfutures.nim` | finished/failed関数（403-414行目） |
| 5-4 | asyncfutures.nim | `lib/pure/asyncfutures.nim` | and演算子（431-445行目） |
| 5-5 | asyncfutures.nim | `lib/pure/asyncfutures.nim` | or演算子（447-457行目） |
| 5-6 | asyncfutures.nim | `lib/pure/asyncfutures.nim` | all関数（459-516行目） |

**主要処理フロー**:
- **362-376行目**: finished=trueでerror確認、未完了ならValueError
- **431-445行目**: 両方完了でcomplete、一方failでfail
- **459-516行目**: void版と値版で処理分岐、全完了で結果配列返却

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

```
アプリケーションコード / asyncdispatch
    │
    ├─ newFuture[T](fromProc)
    │      └─ setupFutureBase
    │            ├─ new(result)
    │            └─ [debug] getStackTraceEntries()
    │
    ├─ addCallback(cb)
    │      ├─ [finished] callSoon(cb)
    │      └─ [!finished] callbacks.add(cb)
    │
    ├─ complete(val)
    │      ├─ checkFinished()
    │      ├─ value = val
    │      ├─ finished = true
    │      └─ callbacks.call()
    │             └─ callSoon(each callback)
    │
    ├─ fail(error)
    │      ├─ checkFinished()
    │      ├─ error = error
    │      ├─ errorStackTrace = getStackTrace()
    │      ├─ finished = true
    │      └─ callbacks.call()
    │
    └─ read()
           ├─ [finished & !error] return value
           ├─ [finished & error] raise error
           └─ [!finished] raise ValueError
```

### データフロー図

```
[非同期操作]           [Future]              [コールバック/await]

newFuture() ───────▶ Future生成
                          │
                          │ finished=false
                          ▼
              ┌─────────────────────┐
              │   callbacks: []     │
              │   value: default    │
              │   error: nil        │
              └─────────────────────┘
                          │
addCallback(cb) ──────────│
                          │
                          ▼
              ┌─────────────────────┐
              │   callbacks: [cb]   │
              └─────────────────────┘
                          │
complete(result) ─────────│
                          │
                          ▼
              ┌─────────────────────┐
              │   finished: true    │
              │   value: result     │
              │   callbacks: []     │
              └─────────────────────┘
                          │
                          │ callbacks.call()
                          ▼
                    callSoon(cb)
                          │
                          ▼
                    cb() 実行
                          │
read() ◀──────────────────│
    │
    ▼
result取得
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| asyncfutures.nim | `lib/pure/asyncfutures.nim` | メインソース | Future型の実装 |
| asyncdispatch.nim | `lib/pure/asyncdispatch.nim` | 利用元 | ディスパッチャとcallSoonの実装 |
| asyncmacro.nim | `lib/pure/asyncmacro.nim` | 利用元 | async/awaitマクロでFutureを使用 |
| system/stacktraces.nim | `lib/system/stacktraces.nim` | 依存 | スタックトレース取得 |
