# 機能設計書 61-DCDサーバー再起動

## 概要

本ドキュメントは、serve-dにおけるDCDサーバー再起動機能（served/restartServer）の設計を記述する。LSPクライアントからのリクエストに応じて、serve-dが管理する全てのDCDサーバーインスタンスを再起動する機能である。

### 本機能の処理概要

**業務上の目的・背景**：DCD（D Completion Daemon）はD言語のコード補完・定義ジャンプ等の機能を提供するサーバーである。DCDサーバーが不安定な状態に陥った場合や、設定変更後にサーバーの状態をリフレッシュする必要がある場合に、全DCDサーバーインスタンスを再起動する手段が必要となる。本機能はDCD起動失敗時のリカバリや、開発者が明示的にDCDの状態をリセットしたい場合に使用される。

**機能の利用シーン**：エディタ上でコード補完が動作しない、定義ジャンプが正常に機能しないなどの問題が発生した場合に、ユーザーがコマンドパレット等から手動でDCDサーバーの再起動を実行する。また、DCD起動失敗通知を受けた後のリカバリ操作としても利用される。

**主要な処理内容**：
1. バックエンドに登録された全ワークスペースインスタンスを走査する
2. 各インスタンスがDCDComponentを保持しているか確認する
3. DCDComponentを持つインスタンスに対してrestartServer()を呼び出す
4. 全インスタンスの再起動完了を待機し、完了後にtrueを返却する

**関連システム・外部連携**：DCDサーバープロセスとの連携。DCDサーバーの停止・再起動はworkspace-dのDCDComponentを通じて行われる。

**権限による制御**：特別な権限制御はない。LSPクライアントが当該メソッドを呼び出せる状態であれば実行可能。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 9 | DCD起動失敗通知 | 遷移先機能 | DCD起動失敗後にユーザーがDCDサーバーの再起動を試みる |
| 40 | DCDサーバー再起動（served/restartServer） | 主画面 | 全DCDサーバーインスタンスを再起動する |

## 機能種別

サーバー管理操作（プロセス再起動）

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| (なし) | - | - | パラメータなしのリクエスト | - |

### 入力データソース

LSPクライアントからの `served/restartServer` メソッド呼び出し。パラメータは不要。

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| result | bool | 再起動完了時にtrueを返却 |

### 出力先

LSPクライアントへのレスポンス（JSON-RPC応答）。

## 処理フロー

### 処理シーケンス

```
1. served/restartServerリクエストを受信
   └─ restartServer()関数が呼び出される
2. 全バックエンドインスタンスを走査
   └─ backend.instancesをforeachで反復
3. 各インスタンスでDCDComponentの有無を確認
   └─ instance.has!DCDComponentで判定
4. DCDComponentを持つインスタンスのrestartServer()を呼び出し
   └─ Future!voidとして非同期呼び出しを記録
5. 全Futureの完了を待機
   └─ joinAll(fut)で全再起動完了を待つ
6. trueを返却
```

### フローチャート

```mermaid
flowchart TD
    A[served/restartServer リクエスト受信] --> B[空のFutureリストを作成]
    B --> C{全インスタンスを走査}
    C -->|次のインスタンス| D{DCDComponent あり?}
    D -->|Yes| E[instance.get!DCDComponent.restartServer をFutureリストに追加]
    D -->|No| C
    E --> C
    C -->|走査完了| F[joinAll で全Futureの完了を待機]
    F --> G[true を返却]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-61-01 | 全インスタンス再起動 | DCDComponentを持つ全てのワークスペースインスタンスのDCDサーバーを再起動する | 常時 |
| BR-61-02 | 同期完了 | 全DCDサーバーの再起動が完了するまでレスポンスを返さない | 常時 |
| BR-61-03 | 非DCDインスタンスのスキップ | DCDComponentを持たないインスタンスはスキップする | 常時 |

### 計算ロジック

特になし。

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

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

データベース操作はない。DCDサーバープロセスの再起動のみ。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | DCDプロセス再起動失敗 | DCDサーバーバイナリが見つからない/実行権限がない場合 | DCDComponentの内部でエラーハンドリングされる |

### リトライ仕様

本機能自体にリトライ機構はない。クライアント側から再度リクエストを送信することで再実行可能。

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

トランザクション管理は不要。各DCDサーバーの再起動は独立して行われる。

## パフォーマンス要件

DCDサーバーの再起動にはプロセスの停止・起動が伴うため、数秒程度の遅延が発生しうる。全インスタンスの再起動をjoinAllで並行待機するため、直列実行よりは高速に完了する。

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

外部プロセス（DCDサーバー）の起動を伴うため、DCDバイナリのパスが信頼できるものであることを前提とする。パス設定は設定変更処理（機能No.5）で管理される。

## 備考

- `@protocolMethod("served/restartServer")` アノテーションにより、LSPメソッドとして登録される
- 戻り値がboolであるため、同期的なリクエスト・レスポンスパターンで動作する
- DCDComponentのrestartServer()はFuture!voidを返す非同期APIである

---

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

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

### 推奨読解順序

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

DCDComponent型とワークスペースインスタンスの関係を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | complete.d | `source/served/commands/complete.d` | restartServer関数とkillServer関数の定義位置を確認 |

**読解のコツ**: D言語の `@protocolMethod` アノテーションは、LSPメソッド名とD言語関数を対応付けるUDA（User-Defined Attribute）である。`has!T` と `get!T` はテンプレート関数で、インスタンスが特定コンポーネントを持つか確認し取得する。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | complete.d | `source/served/commands/complete.d` | restartServer関数（1376-1385行目） |

**主要処理フロー**:
1. **1377行目**: `@protocolMethod("served/restartServer")` によりLSPメソッドとして登録
2. **1379行目**: `Future!void[]` のリストを初期化
3. **1380-1382行目**: `backend.instances` を走査し、DCDComponentを持つインスタンスのrestartServerをFutureリストに追加
4. **1383行目**: `joinAll(fut)` で全Futureの完了を待機
5. **1384行目**: `true` を返却

#### Step 3: DCDComponent層を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | (workspace-d内部) | `workspace-d/source/workspaced/com/dcd.d` | DCDComponent.restartServer()の実装。DCDサーバープロセスの停止と再起動を行う |

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

```
restartServer() [complete.d:1377-1385]
    |
    +-- backend.instances (全ワークスペースインスタンスの列挙)
    |
    +-- instance.has!DCDComponent (DCDComponent保持チェック)
    |
    +-- instance.get!DCDComponent.restartServer() (各DCDサーバー再起動)
    |       |
    |       +-- [workspace-d内部] DCDサーバープロセスの停止
    |       +-- [workspace-d内部] DCDサーバープロセスの再起動
    |
    +-- joinAll(fut) (全Futureの完了待機)
```

### データフロー図

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

served/restartServer  ──▶  restartServer()               ──▶  bool (true)
(LSPリクエスト)              |
                            +-- 全インスタンス走査
                            +-- DCDComponent.restartServer()
                            +-- joinAll(全Future待機)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| complete.d | `source/served/commands/complete.d` | ソース | restartServer関数の定義（1376-1385行目） |
| extension.d | `source/served/extension.d` | ソース | バックエンドインスタンス管理、公開インポート |
| types.d | `source/served/types.d` | ソース | 共通型定義、設定構造体 |
