# 画面設計書 41-DCDサーバー停止（served/killServer）

## 概要

本ドキュメントは、serve-d LSPサーバーにおけるDCDサーバー停止機能（`served/killServer`）の画面設計書である。クライアント（エディタ）からのカスタム通知により、serve-dが管理する全DCDサーバーインスタンスを即座に停止する処理を定義する。

### 本画面の処理概要

本機能は、serve-dが起動・管理している全てのDCD（D Completion Daemon）サーバーインスタンスを一括停止するためのカスタムLSP通知ハンドラである。

**業務上の目的・背景**：DCDサーバーはD言語のコード補完を提供するバックエンドプロセスであり、メモリリークやキャッシュ不整合などの問題が発生した際に、明示的にサーバーを停止させる手段が必要である。また、エディタの終了前やプロジェクト切り替え時に、不要なリソースを解放する目的でも使用される。`served/restartServer`（No.40）が再起動であるのに対し、本機能は単純な停止のみを行い、再起動は行わない。

**画面へのアクセス方法**：エディタのコマンドパレット等から`served/killServer`通知をserve-dに送信する。code-dなどのVSCode拡張機能からはコマンドとして直接呼び出し可能である。

**主要な操作・処理内容**：
1. クライアントから`served/killServer`通知を受信する
2. バックエンドに登録された全インスタンスを走査する
3. 各インスタンスがDCDComponentを保持しているか確認する
4. DCDComponentを持つインスタンスに対してkillServer()を呼び出し、DCDサーバーを停止する

**画面遷移**：
- 遷移元：エディタのコマンドパレット、DCD管理フロー内のDCDサーバー停止操作
- 遷移先：なし（通知であるためレスポンスは返却しない）
- 関連画面：No.40 DCDサーバー再起動（served/restartServer）

**権限による表示制御**：LSPプロトコル上の権限制御は存在しない。クライアントが本通知を送信できる限り、全DCDインスタンスが停止される。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 62 | DCDサーバー停止 (served/killServer) | 主機能 | 全DCDサーバーインスタンスを停止する |

## 画面種別

カスタムLSP通知ハンドラ（protocolNotification）

## URL/ルーティング

LSPカスタム通知メソッド: `served/killServer`

## 入出力項目

### 入力パラメータ

| 項目名 | 型 | 必須 | 説明 |
|--------|-----|------|------|
| （なし） | - | - | 本通知はパラメータを受け取らない |

### 出力パラメータ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| （なし） | - | 通知（notification）であるためレスポンスは返却しない |

## 表示項目

本機能はバックエンド通知であり、画面表示項目は存在しない。DCDサーバーが停止されると、以後のコード補完リクエストが応答しなくなるため、エディタ側で補完機能が利用できなくなる状態となる。

## イベント仕様

### 1-killServer通知受信

クライアントから`served/killServer`通知を受信すると、以下の処理が実行される。

1. `backend.instances`から全ワークスペースインスタンスを取得
2. 各インスタンスについて`instance.has!DCDComponent`でDCDコンポーネントの有無を確認
3. DCDコンポーネントを持つインスタンスに対して`instance.get!DCDComponent.killServer()`を呼び出し
4. 全インスタンスのDCDサーバープロセスが停止される

`served/restartServer`（No.40）とは異なり、killServerは`@protocolNotification`として実装されており、戻り値を返さない。また、restartServerがFutureを使って非同期に完了を待機するのに対し、killServerは同期的にkillを実行する。

## データベース更新仕様

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

本機能はデータベースへのアクセスを行わない。DCDサーバープロセスの停止のみを行う。

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| - | - | - | データベースアクセスなし |

## メッセージ仕様

| メッセージID | 種別 | 表示条件 | メッセージ内容 |
|-------------|------|---------|--------------|
| - | - | - | 本通知は特にクライアントへのメッセージを送信しない |

## 例外処理

- DCDComponentを持たないインスタンスは単純にスキップされる
- DCDサーバーが既に停止している場合も、エラーとはならない（killServer内部で安全に処理される）
- バックエンドインスタンスが存在しない場合、ループが空で実行されるためエラーは発生しない

## 備考

- `served/killServer`は`@protocolNotification`として実装されており、クライアントにレスポンスを返さない点が`served/restartServer`（`@protocolMethod`でboolを返す）と異なる
- DCDサーバー停止後にコード補完が必要な場合は、`served/restartServer`による再起動が必要
- 本機能はDCD管理フロー（画面遷移図参照）において、DCDサーバーを明示的に停止する手段として位置付けられている

---

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

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

### 推奨読解順序

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

DCDサーバー停止にはパラメータ型が不要であるため、主にDCDComponentのインターフェースを理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | types.d | `source/served/types.d` | backend（LazyWorkspaceD）やactiveInstanceの定義。518行目で`__gshared LazyWorkspaceD backend`が宣言されている |

**読解のコツ**: `backend.instances`はWorkspaceD.Instanceの配列であり、各インスタンスが個別のDCDサーバーを管理している。`has!T`/`get!T`パターンでコンポーネントの有無確認と取得を行うのはworkspace-dの標準パターンである。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | complete.d | `source/served/commands/complete.d` | killServer関数の実装。1388行目の`@protocolNotification("served/killServer")`アノテーションと1389-1394行目の関数本体 |

**主要処理フロー**:
1. **1388行目**: `@protocolNotification("served/killServer")`デコレータでLSP通知ハンドラとして登録
2. **1389行目**: `void killServer()`関数定義（引数なし、戻り値なし）
3. **1391行目**: `foreach (instance; backend.instances)` で全インスタンスを走査
4. **1392行目**: `if (instance.has!DCDComponent)` でDCDコンポーネントの存在確認
5. **1393行目**: `instance.get!DCDComponent.killServer()` でDCDサーバーを停止

#### Step 3: 関連コードを理解する

restartServerとの違いを理解するために、同一ファイル内の`restartServer`関数も参照する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | complete.d | `source/served/commands/complete.d` | 1376-1385行目のrestartServer。`@protocolMethod`で宣言され、Futureで非同期待機し`bool`を返す点がkillServerと対照的 |
| 3-2 | extension.d | `source/served/extension.d` | 42行目でcomplete.dモジュールがpublic importされ、LSPルーターに登録される仕組み |

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

```
served/killServer (LSP通知)
    │
    └─ killServer() [complete.d:1389]
           │
           └─ foreach (instance; backend.instances)
                  │
                  ├─ instance.has!DCDComponent [存在確認]
                  │
                  └─ instance.get!DCDComponent.killServer() [DCD停止]
```

### データフロー図

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

served/killServer ───▶ killServer()                ───▶ (なし: void)
通知（パラメータなし）      │
                        ├─ backend.instances走査
                        │
                        └─ DCDComponent.killServer()
                           (各DCDプロセスを停止)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| complete.d | `source/served/commands/complete.d` | ソース | killServer関数の実装（1388-1394行目） |
| extension.d | `source/served/extension.d` | ソース | complete.dモジュールのpublic import・LSPルーター登録 |
| types.d | `source/served/types.d` | ソース | backend（LazyWorkspaceD）の定義（518行目） |
| protoext.d | `source/served/lsp/protoext.d` | ソース | LSPプロトコル拡張型の定義 |
