# 機能設計書 74-LSPサーバー基盤 (serve-d:serverbase)

## 概要

本ドキュメントは、serve-dのサブパッケージ `serve-d:serverbase` の設計を記述する。LSPサーバーの基本機能であるファイバーマネージャ、非同期処理、イベントシステム、サーバー設定管理を提供するサブパッケージである。

### 本機能の処理概要

**業務上の目的・背景**：LSPサーバーとして動作するためのフレームワーク機能を提供する。serve-dのメインモジュールがこのサブパッケージをmixinすることで、ファイバーベースの非同期処理、UDA（User Defined Attribute）ベースのイベントルーティング、ワークスペースごとの設定管理、GCの定期的なコレクションといったサーバー基盤機能を利用できるようになる。

**機能の利用シーン**：serve-dのメインモジュール（extension.d）が`mixin LanguageServerRouter`を使用してサーバーを構成する際に、本サブパッケージの全機能が統合される。起動時からシャットダウンまでの全ライフサイクルにわたって動作する。

**主要な処理内容**：
1. LanguageServerRouterミキシン：LSPサーバーのメインループ・初期化・シャットダウンの枠組み提供
2. EventProcessor：UDAベースのプロトコルメソッド/通知のルーティングシステム
3. FiberManager：複数ファイバーのスケジューリングと実行管理
4. 非同期処理（async）：spawnFiber、setTimeout、setImmediateによる非同期タスク管理
5. サーバー設定（ConfigHandler）：ワークスペース単位の設定管理と変更通知
6. GC管理：定期的なGC.collectとGC.minimizeの実行

**関連システム・外部連携**：serve-d:lspサブパッケージ（RPCProcessor）、serve-d:protocolサブパッケージ（型定義）と連携して動作する。

**権限による制御**：なし（サーバーフレームワークとして動作）

## 関連画面

本サブパッケージは直接的に画面と関連しない。全てのLSP機能の基盤として間接的に使用される。

## 機能種別

基盤ライブラリ / サーバーフレームワーク

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| ExtensionModule | module | Yes | サーバー拡張モジュール（memberModulesとinitialize関数を定義） | memberModulesフィールドとinitialize関数が必須 |
| serverConfig | LanguageServerConfig | No | サーバー設定（デフォルトページ数、GC設定等） | デフォルト値あり |

### 入力データソース

- serve-dメインモジュール（extension.d）からのmixin宣言
- LSPクライアントからの設定変更通知（workspace/didChangeConfiguration）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| LanguageServerConfig | struct | defaultPages, fiberPageSize, gcCollectSeconds等のサーバー設定 |
| EventProcessorConfig | struct | イベントプロセッサの設定（重複メソッド許可リスト等） |
| ConfigWorkspace | struct | ワークスペース別設定（URI、名前なしワークスペース判定等） |

### 出力先

serve-d内部モジュールへのフレームワーク機能提供

## 処理フロー

### 処理シーケンス

```
1. サーバー起動
   └─ LanguageServerRouterミキシンが適用され、stdin/stdoutをRPC用に切り替え
2. RPCプロセッサ初期化
   └─ FileReaderとRPCProcessorファイバーを作成
3. メインループ開始
   └─ RPCProcessorとFiberManagerを交互に呼び出し
4. イベント処理
   └─ EventProcessorがUDAベースでメソッドをディスパッチ
5. 設定同期
   └─ ConfigHandlerがワークスペースごとの設定を管理
6. GC管理
   └─ 設定された間隔でGC.collectとGC.minimizeを実行
7. シャットダウン
   └─ shutdownRequested=trueでループを抜け、exitで終了
```

### フローチャート

```mermaid
flowchart TD
    A[サーバー起動] --> B[stdin/stdout切り替え]
    B --> C[RPCProcessor作成]
    C --> D[メインループ]
    D --> E{RPCメッセージあり?}
    E -->|Yes| F[EventProcessorでディスパッチ]
    E -->|No| G[FiberManager.call]
    F --> G
    G --> H{shutdownRequested?}
    H -->|No| D
    H -->|Yes| I[exit通知待ち]
    I --> J[プロセス終了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-74-01 | stdin/stdout切り替え | 起動時にstdinは/dev/null（NUL）に、stdoutはstderrにリダイレクトし、元のstdin/stdoutはRPC専用に保持 | サーバー起動時 |
| BR-74-02 | UDAベースルーティング | @protocolMethod、@protocolNotification等のUDAが付与された関数を自動的にLSPメソッドとして登録 | コンパイル時 |
| BR-74-03 | 設定変更通知 | workspace/didChangeConfigurationを受信した際、各ワークスペースの設定を更新し@onConfigChangedハンドラを呼び出す | 設定変更時 |
| BR-74-04 | GC管理 | gcCollectSecondsの間隔でGC.collect、gcMinimizeTimes回に1回GC.minimizeを実行 | 定期的 |
| BR-74-05 | ファイバー管理 | FiberManagerが全ファイバーのスケジューリングを行い、終了したファイバーを自動除去する | 常時 |

### 計算ロジック

特になし。

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

本機能ではデータベース操作は行わない。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | static assert | ExtensionModuleにinitialize関数がない場合 | コンパイルエラーとして報告 |
| - | Exception | 設定同期（workspace/configuration）の応答が不正な形式の場合 | errorログ出力、フォールバック設定使用 |
| - | assert | globalConfigurationが初期化前にアクセスされた場合 | assert失敗 |

### リトライ仕様

設定同期が失敗した場合、allowConfigurationRequest=falseでフォールバック処理を行う。

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

不要（ステートレスなイベント処理）。

## パフォーマンス要件

- ファイバーベースの協調的マルチタスク処理
- デフォルトファイバーページ数: 20、ページサイズ: 4096バイト
- GC.collect: デフォルト30秒ごと、GC.minimize: 5回に1回

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

stdin/stdoutの切り替えにより、LSPプロトコル以外のstdout出力を防止する。

## 備考

- `LanguageServerRouter`はD言語のmixin templateとして実装されており、コンパイル時にサーバー構造が決定される
- EventProcessorは`memberModules`フィールドに列挙されたモジュールを走査し、UDAが付与された全関数を自動登録する
- `@initializeHook`、`@onInitialize`、`@onRegisteredComponents`、`@onProjectAvailable`等の多様なライフサイクルフックが提供される

---

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

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

### 推奨読解順序

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

サーバー設定とイベントシステムの基本構造を把握する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | serverbase.d | `serverbase/source/served/serverbase.d` | LanguageServerConfig構造体（26-41行目）とstdin/stdout切り替え（11-23行目） |
| 1-2 | serverconfig.d | `serverbase/source/served/utils/serverconfig.d` | ConfigWorkspace構造体（27-57行目）とConfigHandler mixin（59-456行目） |
| 1-3 | events.d | `serverbase/source/served/utils/events.d` | protocolMethod、protocolNotification等のUDA定義（14-36行目） |

**読解のコツ**: D言語のmixin templateとUDA（ユーザー定義属性）がフレームワークの中核技術。`@protocolMethod("textDocument/completion")`のようなUDAがコンパイル時に走査され、LSPメソッドハンドラとして自動登録される。

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

LanguageServerRouterの起動と初期化フローを確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | serverbase.d | `serverbase/source/served/serverbase.d` | LanguageServerRouter mixin template（65-100行目）: ExtensionModuleの要件とインポート |

**主要処理フロー**:
1. **11-23行目**: `shared static this()`でstdinを/dev/null、stdoutをstderrにリダイレクト
2. **65-67行目**: `mixin template LanguageServerRouter`の宣言とExtensionModuleの検証
3. **96-97行目**: `serverInitializeCalled`フラグによる初期化状態管理

#### Step 3: ファイバーマネージャを理解する

協調的マルチタスク処理の仕組みを確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | fibermanager.d | `serverbase/source/served/utils/fibermanager.d` | FiberManager構造体（16-80行目）: ファイバーの追加・実行・除去 |

**主要処理フロー**:
- **18-28行目**: FiberInfo構造体（名前、ファイバー本体、実行時間計測、ステップ数）
- **49-80行目**: callメソッドで全ファイバーを順次呼び出し、終了したものを除去

#### Step 4: 非同期処理を理解する

spawnFiberとsetTimeoutによる非同期タスク管理。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | async.d | `serverbase/source/served/utils/async.d` | spawnFiber関数（17-28行目）、parallelMain関数（31-63行目）、setTimeout関数（73-76行目） |

#### Step 5: 設定管理を理解する

ワークスペース別設定とConfigHandlerの動作を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 5-1 | serverconfig.d | `serverbase/source/served/utils/serverconfig.d` | ConfigHandler mixin（59行目以降）: perWorkspaceConfigurationStore、globalConfiguration、設定同期ロジック |

**主要処理フロー**:
- **153-203行目**: `postInit_setupConfig`で初期化時にワークスペース設定を準備
- **205-225行目**: `setupConfig_Initialized`でinitializedイベント後に設定をロード
- **256-268行目**: `didChangeConfiguration`でクライアントからの設定変更を処理
- **283-358行目**: `processConfigChange`で設定変更を全ワークスペースに反映

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

```
LanguageServerRouter (mixin template)
    │
    ├─ serverbase.d
    │      ├─ stdin/stdout切り替え
    │      └─ LanguageServerConfig
    │
    ├─ EventProcessor (events.d)
    │      ├─ @protocolMethod ハンドラ登録
    │      ├─ @protocolNotification ハンドラ登録
    │      ├─ @initializeHook / @onInitialize
    │      └─ @onRegisteredComponents / @onProjectAvailable
    │
    ├─ FiberManager (fibermanager.d)
    │      ├─ FiberInfo (名前, 実行時間, ステップ数)
    │      └─ call() (全ファイバー実行)
    │
    ├─ async (async.d)
    │      ├─ spawnFiber
    │      ├─ setTimeout / setImmediate
    │      └─ parallelMain
    │
    └─ ConfigHandler (serverconfig.d)
           ├─ perWorkspaceConfigurationStore
           ├─ globalConfiguration
           ├─ syncConfiguration
           └─ @onConfigChanged / @onConfigFinished
```

### データフロー図

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

initializeリクエスト ──────▶ LanguageServerRouter ──────▶ InitializeResult
  (クライアント)                (initialize関数呼び出し)

設定変更通知 ──────────────▶ ConfigHandler ─────────────▶ @onConfigChanged
  (workspace/didChange...)     (processConfigChange)       (各モジュールに通知)

LSPリクエスト/通知 ────────▶ EventProcessor ────────────▶ ハンドラ関数呼び出し
  (JSON-RPCメッセージ)         (UDAベースディスパッチ)

非同期タスク ──────────────▶ FiberManager ──────────────▶ ファイバー実行
  (spawnFiber呼び出し)         (callメソッド)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| serverbase.d | `serverbase/source/served/serverbase.d` | ソース | LSPサーバーのメインフレームワーク（LanguageServerRouter mixin） |
| events.d | `serverbase/source/served/utils/events.d` | ソース | UDAベースのイベントシステム（protocolMethod, protocolNotification等） |
| fibermanager.d | `serverbase/source/served/utils/fibermanager.d` | ソース | ファイバーのスケジューリングと実行管理 |
| async.d | `serverbase/source/served/utils/async.d` | ソース | 非同期処理ユーティリティ（spawnFiber, setTimeout） |
| serverconfig.d | `serverbase/source/served/utils/serverconfig.d` | ソース | ワークスペース別設定管理（ConfigHandler mixin） |
| memory.d | `serverbase/source/served/utils/memory.d` | ソース | メモリ管理ユーティリティ |
