# 機能設計書 112-tasks

## 概要

本ドキュメントは、Nim標準ライブラリの`tasks`モジュールの機能設計について記載する。このモジュールは並列プログラミングのための基本プリミティブとしてTaskオブジェクトを提供する。

### 本機能の処理概要

tasksモジュールは、関数呼び出しとその引数をカプセル化したTaskオブジェクトを作成し、後から実行できるようにするための機能を提供する。スレッドプールやワーカーシステムでのタスク実行に最適化されている。

**業務上の目的・背景**：並列・並行プログラミングにおいて、処理単位を抽象化して管理する必要がある。このモジュールは、関数とその引数をスレッド間で安全に受け渡すためのメカニズムを提供し、`malebolgia`、`taskpools`、`weave`などの高レベル並列ライブラリの基盤となる。

**機能の利用シーン**：
- スレッドプールへのタスク投入
- 非同期処理のスケジューリング
- ワーカースレッドでの遅延実行
- 関数呼び出しのシリアライズ

**主要な処理内容**：
1. `toTask(expr)` - 関数呼び出し式をTaskオブジェクトに変換
2. `invoke(task)` - Taskを実行
3. 引数のisolation検証（スレッド安全性の保証）
4. スクラッチ領域の動的割り当てと解放

**関連システム・外部連携**：
- isolationモジュール（スレッド安全なデータ転送）
- typedthreadsモジュール（スレッド管理）
- 各種並列処理ライブラリ（malebolgia, taskpools等）

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

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | - | - | プログラム内部で使用するライブラリ機能 |

## 機能種別

並列処理 / メタプログラミング

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| e | typed{nkCall等} | Yes | 関数呼び出し式 | GC安全性チェック、クロージャ禁止 |
| res | pointer | No | 戻り値の格納先（invoke時） | nil可 |

### 入力データソース

コンパイル時に解析される関数呼び出し式

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| Task | object | コールバック、引数ポインタ、デストラクタを含むオブジェクト |

### 出力先

メモリ上のオブジェクト（共有メモリ割り当て）

## 処理フロー

### 処理シーケンス

```
1. toTaskマクロが関数呼び出し式を解析
   └─ 引数の型情報を取得
   └─ GC安全性とクロージャチェック

2. スクラッチオブジェクト型を動的生成
   └─ 各引数をフィールドとして持つ構造体

3. 引数をisolate経由でスクラッチ領域にコピー
   └─ allocShared0で共有メモリ割り当て
   └─ isolate() -> extract()パターンで安全にコピー

4. ラッパープロシージャを生成
   └─ スクラッチからデータを復元して元の関数を呼び出し

5. Taskオブジェクトを構築して返却
   └─ callback: ラッパープロシージャ
   └─ args: スクラッチ領域ポインタ
   └─ destroy: デストラクタプロシージャ
```

### フローチャート

```mermaid
flowchart TD
    A[toTask呼び出し] --> B{引数あり?}
    B -->|Yes| C[スクラッチ型生成]
    B -->|No| D[引数なしTask生成]
    C --> E[メモリ割り当て]
    E --> F[引数をisolate]
    F --> G[ラッパーproc生成]
    G --> H[Task構築]
    D --> H
    H --> I[Task返却]

    J[invoke呼び出し] --> K[callback実行]
    K --> L{戻り値あり?}
    L -->|Yes| M[resに格納]
    L -->|No| N[終了]
    M --> N
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-112-01 | GC安全性 | toTaskに渡す関数はGC安全でなければならない | threadsオプション有効時 |
| BR-112-02 | クロージャ禁止 | クロージャは使用不可 | 常時 |
| BR-112-03 | varパラメータ禁止 | var引数を持つ関数は使用不可 | 常時 |
| BR-112-04 | typed/untypedパラメータ禁止 | マクロ的引数は使用不可 | 常時 |
| BR-112-05 | isolation必須 | 引数はisolate可能でなければならない | 常時 |

### 計算ロジック

特になし

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

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

該当なし

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | コンパイルエラー | GC unsafe関数の使用 | gcsafe関数に修正 |
| - | コンパイルエラー | クロージャの使用 | nimcallプロシージャに変更 |
| - | コンパイルエラー | var引数の使用 | 参照を避ける設計に変更 |
| - | コンパイルエラー | isolate不可能な引数 | Isolated[T]を使用 |

### リトライ仕様

該当なし

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

該当なし

## パフォーマンス要件

- スクラッチ領域はallocShared0で割り当て（スレッド間共有可能）
- デストラクタは自動的に呼び出され、メモリリークを防止

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

- isolationメカニズムによりスレッド安全性を保証
- GC安全性チェックによりデータ競合を防止

## 備考

- Task型はcopy不可（`=copy`がエラー）
- 複数回invokeすることは可能

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | tasks.nim | `lib/std/tasks.nim` | Task型の定義（63-66行目） |
| 1-2 | isolation.nim | `lib/std/isolation.nim` | Isolated[T]型の定義（18-19行目） |

**読解のコツ**: Task型は3つのポインタ（callback, args, destroy）で構成される。callbackはタスク実行用、argsは引数データ、destroyはクリーンアップ用。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | tasks.nim | `lib/std/tasks.nim` | toTaskマクロ（126-277行目） |

**主要処理フロー**:
1. **134-135行目**: 戻り値の型を確認（void判定）
2. **137-138行目**: 関数シンボルを解析
3. **140-145行目**: GC安全性とクロージャチェック
4. **147-198行目**: 引数ありの場合のスクラッチオブジェクト生成
5. **235-257行目**: ラッパープロシージャ生成
6. **248-257行目**: Taskオブジェクト構築

#### Step 3: 補助関数を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | tasks.nim | `lib/std/tasks.nim` | `=destroy`（73-85行目） |
| 3-2 | tasks.nim | `lib/std/tasks.nim` | invoke（87-90行目） |
| 3-3 | tasks.nim | `lib/std/tasks.nim` | checkIsolate（92-101行目） |

**主要処理フロー**:
- **87-90行目**: invokeはcallbackを呼び出すだけのシンプルな実装
- **73-85行目**: デストラクタはdestroy関数を呼び出し、deallocSharedでメモリ解放

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

```
toTask(hello(13))
    │
    ├─ analyseRootSym() - シンボル解析
    │
    ├─ isGcSafe() - GC安全性チェック
    │
    ├─ hasClosure() - クロージャチェック
    │
    ├─ スクラッチオブジェクト生成
    │      ├─ allocShared0()
    │      └─ isolate() / extract()
    │
    ├─ ラッパーproc生成
    │
    └─ Task(callback, args, destroy)
           │
           invoke(task)
               └─ task.callback(task.args, res)
```

### データフロー図

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

hello(13)
    │
    ├─ 関数: hello    ─▶ ラッパーproc生成 ─▶ callback
    │
    └─ 引数: 13       ─▶ isolate/extract ──▶ args (スクラッチ)
                           │
                           └─▶ deallocShared ◀── =destroy
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| tasks.nim | `lib/std/tasks.nim` | ソース | Task型とtoTaskマクロ |
| isolation.nim | `lib/std/isolation.nim` | ソース | Isolated[T]型 |
| typedthreads.nim | `lib/std/typedthreads.nim` | ソース | スレッド管理 |
| macros.nim | `lib/core/macros.nim` | ソース | マクロ支援 |
| typetraits.nim | `lib/pure/typetraits.nim` | ソース | 型特性 |
