# 通知設計書 15-$/progress

## 概要

本ドキュメントは、clojure-lspにおける`$/progress`通知の設計仕様を記載したものです。この通知はサーバーからクライアントへ送信される通知であり、長時間実行される処理の進捗状況をクライアントに報告します。

### 本通知の処理概要

`$/progress`通知は、LSPサーバーで実行中の長時間タスク（プロジェクト初期化、クラスパス解析、依存関係分析など）の進捗状況をエディタに通知するための標準LSP機能です。clojure-lspでは、プロジェクト初期化プロセスの各段階や、ライブラリ補完のためのデータ取得など、時間のかかる処理の進捗をユーザーに可視化します。

**業務上の目的・背景**：この通知はLSP標準仕様の一部であり、ユーザーエクスペリエンスの向上を目的としています。大規模プロジェクトの初期化には時間がかかることがあり、進捗表示がないとサーバーが応答しなくなったように見える可能性があります。進捗通知により、ユーザーは処理が正常に進行していることを確認できます。

**通知の送信タイミング**：以下のイベントで送信されます：
- プロジェクト初期化の各段階（kondo設定検索、キャッシュ検索、クラスパス検出、依存関係分析、プロジェクト分析など）
- 外部ライブラリ補完情報の取得
- JDKソースの分析
- スタブ生成

**通知の受信者**：エディタ（クライアント）がこの通知を受信し、進捗バー、ステータスバー、または専用UIでユーザーに進捗を表示します。

**通知内容の概要**：通知にはプログレストークン（処理識別子）、進捗パーセンテージ（0-100）、現在の処理内容を示すメッセージが含まれます。WorkDoneProgressBegin/Report/Endの3種類の通知で進捗のライフサイクルを管理します。

**期待されるアクション**：ユーザーは進捗表示を確認し、処理の完了を待つことが期待されます。通常、ユーザーからの明示的なアクションは不要です。

## 通知種別

LSP通知（サーバー→クライアント）

## 送信仕様

### 基本情報

| 項目 | 内容 |
|-----|------|
| 送信方式 | 同期 |
| 優先度 | 低 |
| リトライ | なし |

### 送信先決定ロジック

サーバーからクライアントへの一方向通知のため、送信先は接続されているエディタクライアントに固定されます。

## 通知テンプレート

### LSP通知の場合

| 項目 | 内容 |
|-----|------|
| メソッド名 | `$/progress` |
| パラメータ | ProgressParams |
| レスポンス | なし（通知のため） |

### 本文テンプレート

```json
{
  "token": "work-done-token-123",
  "value": {
    "kind": "report",
    "percentage": 45,
    "message": "Analyzing project files"
  }
}
```

プログレス種別：
- `begin`: 進捗開始（title必須）
- `report`: 進捗報告（percentage, message任意）
- `end`: 進捗終了（message任意）

### 添付ファイル

該当なし

## テンプレート変数

| 変数名 | 説明 | データ取得元 | 必須 |
|--------|------|-------------|-----|
| token | プログレストークン | クライアントからの初期化パラメータ / サーバー生成 | Yes |
| kind | プログレス種別（begin/report/end） | lsp.requests/work-done-progress | Yes |
| percentage | 進捗パーセンテージ（0-100） | タスク進捗計算 | No |
| message | 現在のタスク説明 | タスク定義 | No |
| title | 全体タスク名（beginのみ） | タスク定義 | begin時のみ |
| cancellable | キャンセル可能フラグ | 固定false | No |

## 送信トリガー・条件

### トリガー一覧

| トリガー種別 | トリガーイベント | 送信条件 | 説明 |
|------------|----------------|---------|------|
| 初期化 | initialize開始 | progress-tokenが存在 | プロジェクト初期化開始 |
| 初期化 | 各タスク開始/完了 | progress-tokenが存在 | kondo設定/キャッシュ/クラスパス等 |
| 機能実行 | ライブラリ取得開始 | 常に | 補完用ライブラリデータ取得 |
| 初期化 | JDK分析/スタブ生成 | progress-tokenが存在 | 初期化後のバックグラウンドタスク |

### 送信抑止条件

| 条件 | 説明 |
|-----|------|
| progress-tokenがnil | クライアントがprogressをサポートしない場合 |

## 処理フロー

### 送信フロー

```mermaid
flowchart TD
    A[タスク開始] --> B{progress-token存在?}
    B -->|No| C[進捗通知スキップ]
    B -->|Yes| D[publish-progress呼び出し]
    D --> E[work-done-progress構築]
    E --> F[send-notification実行]
    F --> G[クライアントへ通知送信]
    G --> H{タスク完了?}
    H -->|No| I[タスク処理継続]
    I --> D
    H -->|Yes| J[終了]
    C --> K[タスク処理継続]
    K --> L{タスク完了?}
    L -->|No| K
    L -->|Yes| J
```

## データベース参照・更新仕様

### 参照テーブル一覧

| テーブル名 | 用途 | 備考 |
|-----------|------|------|
| なし | - | この通知自体ではDB参照なし |

### 更新テーブル一覧

| テーブル名 | 操作 | 概要 |
|-----------|------|------|
| なし | - | この通知では状態更新は行いません |

## エラー処理

### エラーケース一覧

| エラー種別 | 発生条件 | 対処方法 |
|----------|---------|---------|
| なし | - | この通知でエラーは発生しない |

### リトライ仕様

| 項目 | 内容 |
|-----|------|
| リトライ回数 | 0回 |
| リトライ間隔 | - |
| リトライ対象エラー | - |

## 配信設定

### レート制限

| 項目 | 内容 |
|-----|------|
| 1分あたり上限 | なし |
| 1日あたり上限 | なし |

### 配信時間帯

制限なし

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

進捗通知にはタスク名とパーセンテージのみが含まれ、機密情報は含まれません。特別なセキュリティ考慮は不要です。

## 備考

- LSP標準仕様に準拠（Work Done Progress）
- クライアントがwork-done-tokenを提供しない場合、進捗通知はスキップされます
- 進捗パーセンテージは線形補間（lerp）で計算されます
- fast_tasks/slow_tasksの2種類のタスクセットがあり、キャッシュ使用時はfast_tasksを使用

---

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

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

### 推奨読解順序

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

タスク定義とプログレスパラメータの構造を理解することが重要です。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | startup.clj | `lib/src/clojure_lsp/startup.clj` | fast-tasks/slow-tasks定義（37-57行目）でタスク構造を確認 |
| 1-2 | startup.clj | `lib/src/clojure_lsp/startup.clj` | batched-task/partial-task関数（59-65行目）で進捗計算を確認 |

**読解のコツ**: 各タスクは`:task/start-percent`、`:task/end-percent`、`:task/title`、`:task/id`を持ちます。

#### Step 2: プロトコル定義を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | producer.clj | `lib/src/clojure_lsp/producer.clj` | IProducerプロトコルのpublish-progress定義（9行目）を確認 |

**主要処理フロー**:
- **9行目**: `(publish-progress [this percentage message progress-token])`の4引数シグネチャ

#### Step 3: 実装層を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | server.clj | `cli/src/clojure_lsp/server.clj` | ClojureLspProducerのpublish-progress実装（162-166行目）を確認 |

**主要処理フロー**:
- **162行目**: publish-progress関数定義
- **165行目**: lsp.requests/work-done-progressでLSPリクエスト構築
- **166行目**: send-notificationで`$/progress`通知送信

#### Step 4: 呼び出し元を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | startup.clj | `lib/src/clojure_lsp/startup.clj` | publish-task-progress関数（67-69行目）でタスク進捗送信を確認 |
| 4-2 | startup.clj | `lib/src/clojure_lsp/startup.clj` | initialize-project関数（224-325行目）での使用例を確認 |

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

```
initialize-project / 各種タスク
    │
    └─ startup/publish-task-progress
           │
           ├─ タスク情報抽出
           │      │
           │      ├─ :task/title
           │      ├─ :task/current-percent
           │      └─ :task/start-percent
           │
           └─ producer/publish-progress
                  │
                  ├─ lsp.requests/work-done-progress
                  │      │
                  │      └─ WorkDoneProgressReport構築
                  │
                  └─ jsonrpc.server/send-notification "$/progress"
```

### データフロー図

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

タスク定義                進捗パラメータ構築              $/progress通知
    │                           │
    ├─ start-percent ─▶ percentage計算
    ├─ end-percent            │
    ├─ title ──────────▶ message設定 ──────▶ send-notification
    └─ current-percent        │                      │
                              │                      ▼
progress-token ──────────▶ token設定 ──────▶ クライアントへ通知

                    lerp(start, end, progress)
                    = start + (end - start) * progress
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| server.clj | `cli/src/clojure_lsp/server.clj` | ソース | ClojureLspProducerでのpublish-progress実装 |
| producer.clj | `lib/src/clojure_lsp/producer.clj` | ソース | IProducerプロトコル定義 |
| startup.clj | `lib/src/clojure_lsp/startup.clj` | ソース | タスク定義、publish-task-progress、initialize-project |
| handlers.clj | `lib/src/clojure_lsp/handlers.clj` | ソース | 初期化後タスクでの進捗使用 |
| file_management.clj | `lib/src/clojure_lsp/feature/file_management.clj` | ソース | ライブラリ取得時の進捗使用 |
