# 機能設計書 2-シャットダウン (shutdown)

## 概要

本ドキュメントは、serve-d LSPサーバーにおけるシャットダウン (shutdown) 機能の設計を記述する。LSPクライアントからのshutdownリクエストを処理し、バックエンドの全コンポーネントを停止する。

### 本機能の処理概要

LSPプロトコルに基づき、クライアントがサーバーの終了を要求する際に呼び出されるshutdownメソッドを処理する。backendオブジェクトのshutdownを呼び出して全ワークスペース・コンポーネントを停止し、1秒後にRPCが未終了ならエラーをスローするセーフティタイマーを設定する。

**業務上の目的・背景**：LSPではサーバーのグレースフルシャットダウンが規定されている。クライアント（エディタ）がserve-dを終了させる際、全てのバックエンドコンポーネント（DCD、DUB、DScanner等）を適切に停止する必要がある。リソースリーク防止やDCDサーバープロセスの孤立防止のために本機能が存在する。

**機能の利用シーン**：エディタの終了時、またはユーザーがLSPサーバーの再起動を指示した際にクライアントから呼び出される。

**主要な処理内容**：
1. backendがnullでないことを確認
2. backend.shutdown()を呼び出し、全コンポーネントを停止
3. 1秒後のセーフティタイマーを設定（RPC未終了時にエラーをスロー）
4. JsonValue(null)を返却

**関連システム・外部連携**：LSPクライアントとのJSON-RPC通信。バックエンド経由で管理される全コンポーネント（DCD、DUB等）。

**権限による制御**：特に権限制御は存在しない。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | - | - | shutdown単独の画面は画面機能マッピングに定義されていない |

## 機能種別

システム制御（LSPサーバーシャットダウン）

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| なし | - | - | shutdownリクエストはパラメータを持たない | - |

### 入力データソース

LSPクライアントからのJSON-RPCリクエスト（メソッド名: "shutdown"）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| result | JsonValue(null) | LSP仕様に従いnullを返却 |

### 出力先

LSPクライアントへのJSON-RPCレスポンス

## 処理フロー

### 処理シーケンス

```
1. backendの存在確認
   └─ backendがnullの場合、即座にJsonValue(null)を返却
2. バックエンドシャットダウン
   └─ backend.shutdown()を呼び出し、全コンポーネントを停止
3. セーフティタイマー設定
   └─ 1秒後にRPCがまだ動作中であればError("RPC still running 1s after shutdown")をスロー
4. JsonValue(null)を返却
```

### フローチャート

```mermaid
flowchart TD
    A[shutdownリクエスト受信] --> B{backend != null?}
    B -->|No| C[JsonValue null 返却]
    B -->|Yes| D[backend.shutdown 呼び出し]
    D --> E[1秒セーフティタイマー設定]
    E --> F[JsonValue null 返却]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-01 | バックエンドnullチェック | backendがnullの場合はシャットダウン処理をスキップしnullを返す | backend未初期化時 |
| BR-02 | セーフティタイマー | shutdown後1秒以内にRPCが終了しなければErrorをスロー | 常時 |
| BR-03 | shutdownRequested | グローバル変数shutdownRequestedがtrueに設定される（extension.d 57行目で定義） | shutdownメソッド呼び出し時 |

### 計算ロジック

特になし。

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

本機能ではデータベース操作は発生しない。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| なし | Error | shutdown後1秒以内にRPCが終了しない場合 | Error("RPC still running 1s after shutdown")がスローされプロセス強制終了 |

### リトライ仕様

リトライは行わない。シャットダウンは一度のみ実行される。

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

トランザクションは存在しない。

## パフォーマンス要件

backend.shutdown()は同期的に全コンポーネントの停止を行う。1秒のタイムアウトが設定されている。

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

特になし。

## 備考

- LSP仕様では、shutdownレスポンス後にクライアントがexitNotificationを送信してプロセス終了を指示する。
- shutdownRequestedフラグは他の機能（DCD起動判定等）で参照され、シャットダウン中の不要な処理起動を防止する。
- shared static ~this()デストラクタ（extension.d 1382-1386行目）でもbackend.shutdown()が呼ばれるフォールバックがある。

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | extension.d | `source/served/extension.d` | shutdownRequestedグローバル変数（57行目）: シャットダウン状態フラグ |
| 1-2 | types.d | `source/served/types.d` | backendグローバル変数（LazyWorkspaceD型）: バックエンドインスタンス |

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | extension.d | `source/served/extension.d` | shutdown関数（1078-1088行目）: @protocolMethod("shutdown")でディスパッチされるハンドラ |

**主要処理フロー**:
1. **1081-1082行目**: backendがnullチェック。nullならnull返却
2. **1083行目**: backend.shutdown()呼び出し
3. **1084-1086行目**: 1秒後のセーフティタイマー設定
4. **1087行目**: JsonValue(null)返却

#### Step 3: 関連するシャットダウン処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | extension.d | `source/served/extension.d` | shared static ~this()（1382-1386行目）: デストラクタでのフォールバックシャットダウン |
| 3-2 | extension.d | `source/served/extension.d` | wantsDCDServer関数（972-997行目）: shutdownRequestedフラグの参照例 |

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

```
shutdown()  [@protocolMethod("shutdown")]
    |
    +-- backend.shutdown()   ... 全コンポーネント停止
    |
    +-- setTimeout(1s)       ... セーフティタイマー
    |       |
    |       +-- throw Error("RPC still running 1s after shutdown")
    |
    +-- [返却] JsonValue(null)
```

### データフロー図

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

shutdownリクエスト ───> shutdown()
                          |
                          +-- backend.shutdown()
                          |
                          +-- setTimeout(1s)
                          |
                          +-- JsonValue(null) ───> LSPクライアントへ
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| extension.d | `source/served/extension.d` | ソース | shutdown関数、shutdownRequestedフラグ、デストラクタの実装 |
| types.d | `source/served/types.d` | ソース | backendグローバル変数の型定義 |
