# 機能設計書 47-再開可能コード

## 概要

本ドキュメントは、F#コンパイラサービスにおける再開可能コード（Resumable Code）機能の設計を記述する。

### 本機能の処理概要

再開可能コード機能は、task { } や async { } などの非同期コンピュテーション式の効率的な実装を支援するための低レベルインフラストラクチャである。状態マシン（State Machine）パターンを活用して、中断と再開が可能なコードブロックを実現する。

**業務上の目的・背景**：従来のF#非同期ワークフローは、継続渡しスタイル（CPS）に基づく実装でオーバーヘッドが大きかった。再開可能コードは、C#のasync/awaitと同様の状態マシンベースの実装を可能にし、パフォーマンスを大幅に向上させる。

**機能の利用シーン**：
- task { } コンピュテーション式の実装
- 高性能な非同期処理
- カスタムコンピュテーション式ビルダーの作成
- サーバーサイドの高負荷処理

**主要な処理内容**：
1. ResumableStateMachine構造体による状態管理
2. ResumableCodeデリゲートによるコード片の表現
3. 制御フロー構造（While, TryWith, TryFinally等）のサポート
4. 再開ポイントの管理とジャンプ

**関連システム・外部連携**：F#コンパイラ、.NET IAsyncStateMachine

**権限による制御**：特になし（コンパイラサービス機能）

## 関連画面

本機能はコンパイラサービス機能のため、直接関連する画面はない。

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | - | - | - |

## 機能種別

コンパイラサービス / 非同期処理基盤

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| code | ResumableCode<'Data, 'T> | Yes | 再開可能なコードブロック | - |
| sm | byref<ResumableStateMachine<'Data>> | Yes | 状態マシン参照 | - |

### 入力データソース

コンピュテーション式から変換されたコード

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| 完了フラグ | bool | true: 完了、false: 中断 |
| 結果値 | 'T | コンピュテーション式の結果 |

### 出力先

呼び出し元コンピュテーション式

## 処理フロー

### 処理シーケンス

```
1. 状態マシンの初期化
   └─ ResumableStateMachine構造体の作成
2. ResumableCodeの実行
   └─ Invoke(&sm)でコードを実行
3. 中断ポイントの検出
   └─ falseを返して中断を通知
4. 再開処理
   └─ ResumptionPointに基づいて再開位置にジャンプ
5. 完了処理
   └─ trueを返して完了を通知
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B[状態マシン初期化]
    B --> C[ResumableCode.Invoke]
    C --> D{完了?}
    D -->|true| E[結果を返却]
    D -->|false| F[中断ポイントを保存]
    F --> G[中断を通知]
    G --> H[外部イベント待機]
    H --> I[再開]
    I --> J[ResumptionPointから継続]
    J --> C
    E --> K[終了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-01 | 状態保存 | 中断時にResumptionPointを保存 | 中断時 |
| BR-02 | 状態復元 | 再開時にResumptionPointから継続 | 再開時 |
| BR-03 | 例外伝播 | try/with/finallyで例外を適切に処理 | 例外発生時 |

### 計算ロジック

主要な型と関数:
- `ResumableStateMachine<'Data>`: 状態マシン構造体
- `ResumableCode<'Data, 'T>`: 再開可能コードデリゲート
- `ResumptionFunc<'Data>`: 再開関数デリゲート
- `__useResumableCode`: 再開可能コード使用フラグ
- `__resumableEntry`: 再開エントリポイント取得
- `__resumeAt`: 指定ポイントへのジャンプ

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

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

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | failwith | 不正な__resumableEntry呼び出し | 正しいコンテキストで使用 |
| - | failwith | 不正な__resumeAt呼び出し | 正しいコンテキストで使用 |
| - | failwith | 不正な__stateMachine呼び出し | 正しいコンテキストで使用 |

### リトライ仕様

該当なし

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

該当なし

## パフォーマンス要件

- struct型によるヒープアロケーション回避
- インライン化による関数呼び出しオーバーヘッド削減
- 状態マシンベースの効率的な実装

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

- 低レベルAPI（#nowarn "9", "51"）を使用するため注意が必要
- コンパイラが生成するコードとして設計されており、直接使用は推奨しない

## 備考

再開可能コードはF# 6.0で導入され、task { } コンピュテーション式の高性能実装を可能にした。

---

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

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

### 推奨読解順序

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

状態マシンとコードデリゲートの構造を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | resumable.fs | `src/FSharp.Core/resumable.fs` | **23-26行目**: IResumableStateMachine<'Data>インターフェース |
| 1-2 | resumable.fs | `src/FSharp.Core/resumable.fs` | **28-56行目**: ResumableStateMachine<'Data>構造体 |
| 1-3 | resumable.fs | `src/FSharp.Core/resumable.fs` | **66行目**: ResumableCode<'Data, 'T>デリゲート定義 |

**読解のコツ**: ResumableStateMachineは[<Struct>]で定義されており、ヒープアロケーションを回避する。IAsyncStateMachineを実装することで.NETの非同期インフラと連携する。

#### Step 2: ヘルパー関数を理解する

コンパイラが使用するマジック関数を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | resumable.fs | `src/FSharp.Core/resumable.fs` | **81-82行目**: __useResumableCodeフラグ |
| 2-2 | resumable.fs | `src/FSharp.Core/resumable.fs` | **88-91行目**: __resumableEntry()関数 |
| 2-3 | resumable.fs | `src/FSharp.Core/resumable.fs` | **93-98行目**: __resumeAt関数 |
| 2-4 | resumable.fs | `src/FSharp.Core/resumable.fs` | **100-111行目**: __stateMachine関数 |

**主要処理フロー**:
- **82行目**: __useResumableCodeは静的にfalseを返し、コンパイラが特別な変換を適用
- **89-91行目**: __resumableEntry()は再開エントリポイントを取得

#### Step 3: 制御フロー構造を理解する

再開可能な制御フロー構造の実装を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | resumable.fs | `src/FSharp.Core/resumable.fs` | **119-124行目**: Delay/Zero関数 |
| 3-2 | resumable.fs | `src/FSharp.Core/resumable.fs` | **149-163行目**: Combine関数 |
| 3-3 | resumable.fs | `src/FSharp.Core/resumable.fs` | **199-218行目**: While関数 |
| 3-4 | resumable.fs | `src/FSharp.Core/resumable.fs` | **242-269行目**: TryWith関数 |
| 3-5 | resumable.fs | `src/FSharp.Core/resumable.fs` | **321-343行目**: TryFinally関数 |

#### Step 4: 高レベル構造を理解する

Using, For, Yieldなどの高レベル関数を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | resumable.fs | `src/FSharp.Core/resumable.fs` | **379-390行目**: Using関数 |
| 4-2 | resumable.fs | `src/FSharp.Core/resumable.fs` | **392-404行目**: For関数 |
| 4-3 | resumable.fs | `src/FSharp.Core/resumable.fs` | **411-425行目**: Yield関数 |

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

```
task { } / カスタムコンピュテーション式
    │
    ├─ コンパイラ変換
    │      └─ __stateMachine の呼び出し
    │             ├─ moveNextMethod
    │             ├─ setStateMachineMethod
    │             └─ afterCode
    │
    └─ ResumableStateMachine<'Data>
           │
           ├─ IAsyncStateMachine.MoveNext()
           │      └─ ResumptionDynamicInfo.MoveNext(&sm)
           │
           └─ ResumableCode 実行
                  ├─ Combine (順次実行)
                  │      └─ code1.Invoke → code2.Invoke
                  ├─ While (ループ)
                  │      └─ condition() → body.Invoke
                  ├─ TryWith (例外処理)
                  │      └─ body.Invoke → catch.Invoke
                  ├─ TryFinally (後処理)
                  │      └─ body.Invoke → compensation.Invoke
                  ├─ Using (リソース管理)
                  │      └─ TryFinally + Dispose
                  ├─ For (反復)
                  │      └─ Using + While
                  └─ Yield (中断)
                         └─ __resumableEntry → false返却
```

### データフロー図

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

task { ... }     ───▶  コンパイラ変換          ───▶  ResumableStateMachine
  ソースコード          (IL生成)                     (状態マシン)
    │
    ▼
MoveNext()      ───▶  ResumableCode.Invoke    ───▶  bool (完了/中断)
  呼び出し              (コード実行)
    │
    ▼
ResumptionPoint ───▶  __resumeAt             ───▶  継続実行
  保存値                (再開ジャンプ)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| resumable.fs | `src/FSharp.Core/resumable.fs` | ソース | 再開可能コード基盤 |
| tasks.fs | `src/FSharp.Core/tasks.fs` | ソース | task { } の実装 |
| async.fs | `src/FSharp.Core/async.fs` | ソース | 非同期ワークフローの実装 |
