# 機能設計書 4-終了 (exit)

## 概要

本ドキュメントは、lua-language-serverにおけるLSP終了機能の設計を記載したものである。クライアントからの`exit`通知を受信し、サーバープロセスを終了する。

### 本機能の処理概要

**業務上の目的・背景**：LSPプロトコルにおいて、サーバーの終了は`shutdown`リクエストと`exit`通知の2段階で行われる。`exit`通知は`shutdown`リクエスト後に送信され、サーバープロセスの実際の終了を指示する。この分離により、サーバーは安全にリソースを解放した後にプロセスを終了できる。

**機能の利用シーン**：エディタを閉じる時、またはLSPサーバーを明示的に停止する時に、`shutdown`リクエストの後に自動的に呼び出される。

**主要な処理内容**：
1. exit通知の受信
2. ログ出力（"Server exited."）
3. プロセスの終了（os.exit(0, true)）

**関連システム・外部連携**：LSPクライアント、オペレーティングシステム

**権限による制御**：特になし

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | - | - | 本機能は直接的な画面表示を持たない |

## 機能種別

サーバーライフサイクル管理 / プロセス終了

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| - | - | - | パラメータなし | - |

### 入力データソース

LSPクライアントからのJSON-RPC通知

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| - | - | 通知のため戻り値なし（プロセス終了） |

### 出力先

なし（プロセス終了）

## 処理フロー

### 処理シーケンス

```
1. exit通知の受信
   └─ JSON-RPCでクライアントから通知を受信

2. ログ出力
   └─ log.info('Server exited.')を実行

3. プロセス終了
   └─ os.exit(0, true)を実行
   └─ 正常終了コード0でプロセスを終了
```

### フローチャート

```mermaid
flowchart TD
    A[exit通知受信] --> B[ログ出力]
    B --> C[os.exit 0, true]
    C --> D[プロセス終了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-001 | 正常終了コード | shutdown後のexitは終了コード0 | shutdown後 |
| BR-002 | 異常終了コード | shutdown無しのexitは終了コード1（LSP仕様） | shutdown無し |
| BR-003 | 強制終了 | os.exit(0, true)で全コルーチンを終了 | 常時 |

### 計算ロジック

特になし

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

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

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

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | - | exit通知は常に処理される | - |

### リトライ仕様

リトライ不可（プロセス終了のため）

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

トランザクション管理なし

## パフォーマンス要件

即座にプロセスを終了すること

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

特になし

## 備考

- `exit`は通知であり、レスポンスを返さない
- `os.exit(0, true)`の第2引数`true`は、Luaのガベージコレクタによるfinalizer実行を抑制する
- LSP仕様では、shutdown無しのexitは終了コード1を返すべきとされている

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | provider.lua | `script/provider/provider.lua` | `m.register 'exit'`でハンドラを登録 |

**主要処理フロー**:
1. **167-172行目**: `exit`ハンドラの定義
2. **169行目**: `log.info('Server exited.')`でログ出力
3. **170行目**: `os.exit(0, true)`でプロセス終了

**読解のコツ**: `os.exit(0, true)`の引数について理解することが重要。第1引数はOSへの終了コード（0=正常）、第2引数はLua固有のオプションでfinalizer実行の制御。

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

```
m.register 'exit' (provider.lua:167-172)
    |
    +-- log.info('Server exited.')
    |       └─ ログファイルに出力
    |
    +-- os.exit(0, true)
            └─ プロセス終了（正常終了コード0）
```

### データフロー図

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

(パラメータなし) ──────> provider.lua                      (プロセス終了)
                         m.register 'exit'
                         |
                         +-- log.info()
                         |     (ログ出力)
                         |
                         +-- os.exit(0, true)
                               (プロセス終了)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| provider.lua | `script/provider/provider.lua` | ソース | LSP通知ハンドラの登録・実行 |
| proto.lua | `script/proto/proto.lua` | ソース | LSPプロトコル通信処理 |
| log.lua | `script/log.lua` | ソース | ログ出力機能 |
