# 帳票設計書 6-Thread Pool Report

## 概要

本ドキュメントは、OpenSearchの `_cat/thread_pool` APIが出力するThread Pool Reportの帳票設計書である。各ノードのスレッドプール状態をテキストテーブル形式で出力するCat APIエンドポイントの仕様を定義する。

### 本帳票の処理概要

Thread Pool Reportは、クラスタ内の全ノードについて、各スレッドプールのアクティブスレッド数、キュー待ちタスク数、拒否されたタスク数などを一覧表示する帳票である。スレッドプール名パターンによるフィルタリングが可能。

**業務上の目的・背景**：OpenSearchは内部的に多数のスレッドプール（search、index、write、bulk等）を使用している。各スレッドプールの状態を監視することで、特定の処理がボトルネックになっているか、タスクの拒否が発生しているかを検出でき、パフォーマンスチューニングの指標となる。

**帳票の利用シーン**：スレッドプールの状態監視、拒否タスクの検出、パフォーマンスボトルネック分析、スレッドプール設定の検証に利用される。

**主要な出力内容**：
1. ノード識別情報（ノード名、ノードID、ホスト、IP）
2. スレッドプール情報（名前、タイプ）
3. スレッドプール統計（アクティブ数、プールサイズ、キュー、拒否数、完了数）
4. スレッドプール設定（コア、最大、サイズ、キープアライブ、並列度）

**帳票の出力タイミング**：ユーザーが `GET /_cat/thread_pool` または `GET /_cat/thread_pool/{thread_pool_patterns}` エンドポイントにHTTPリクエストを送信した時点で出力される。

**帳票の利用者**：クラスタ管理者、SRE、パフォーマンスエンジニア。

## 帳票種別

一覧表（テキストテーブル形式のスレッドプール状態一覧）

## 利用画面

| 画面No | 画面名 | URL/ルーティング | 出力操作 |
|--------|--------|-----------------|---------|
| - | Cat スレッドプール | `GET /_cat/thread_pool` | HTTP GETリクエスト |
| - | Cat スレッドプール（指定） | `GET /_cat/thread_pool/{thread_pool_patterns}` | HTTP GETリクエスト |

## 出力形式

### 基本仕様

| 項目 | 内容 |
|-----|------|
| ファイル形式 | テキスト（text/plain）/ JSON（application/json） |
| 用紙サイズ | N/A |
| 向き | N/A |
| ファイル名 | N/A |
| 出力方法 | HTTPレスポンス |
| 文字コード | UTF-8 |

## 帳票レイアウト

### 明細部（デフォルト表示カラム）

| No | 項目名 | 説明 | データ取得元 | 表示形式 |
|----|-------|------|-------------|---------|
| 1 | node_name | ノード名 | DiscoveryNode.getName() | 文字列 |
| 2 | name | スレッドプール名 | ThreadPoolStats.Stats.getName() | 文字列 |
| 3 | active | アクティブスレッド数 | ThreadPoolStats.Stats.getActive() | 右寄せ数値 |
| 4 | queue | キュー内タスク数 | ThreadPoolStats.Stats.getQueue() | 右寄せ数値 |
| 5 | rejected | 拒否されたタスク数 | ThreadPoolStats.Stats.getRejected() | 右寄せ数値 |

### 明細部（オプションカラム - default:false）

| No | 項目名 | 説明 | データ取得元 | 表示形式 |
|----|-------|------|-------------|---------|
| 1 | node_id | ノードID | DiscoveryNode.getId() | 文字列 |
| 2 | ephemeral_node_id | エフェメラルノードID | DiscoveryNode.getEphemeralId() | 文字列 |
| 3 | pid | プロセスID | ProcessInfo.getId() | 数値 |
| 4 | host | ホスト名 | DiscoveryNode.getHostName() | 文字列 |
| 5 | ip | IPアドレス | DiscoveryNode.getHostAddress() | 文字列 |
| 6 | port | トランスポートポート | DiscoveryNode.getAddress().address().getPort() | 数値 |
| 7 | type | スレッドプールタイプ | ThreadPool.Info.getThreadPoolType().getType() | 文字列 |
| 8 | pool_size | プールサイズ | ThreadPoolStats.Stats.getThreads() | 右寄せ数値 |
| 9 | queue_size | 最大キューサイズ | ThreadPool.Info.getQueueSize().singles() | 右寄せ数値 |
| 10 | largest | 最大アクティブスレッド数 | ThreadPoolStats.Stats.getLargest() | 右寄せ数値 |
| 11 | completed | 完了タスク数 | ThreadPoolStats.Stats.getCompleted() | 右寄せ数値 |
| 12 | total_wait_time | 合計待ち時間 | ThreadPoolStats.Stats.getWaitTime() | 右寄せ時間値 |
| 13 | core | コアスレッド数（scalingのみ） | ThreadPool.Info.getMin() | 右寄せ数値 |
| 14 | max | 最大スレッド数（scalingのみ） | ThreadPool.Info.getMax() | 右寄せ数値 |
| 15 | size | 固定スレッド数（fixedのみ） | ThreadPool.Info.getMax() | 右寄せ数値 |
| 16 | keep_alive | キープアライブ時間 | ThreadPool.Info.getKeepAlive() | 右寄せ時間値 |
| 17 | parallelism | 並列度（fork_joinのみ） | ThreadPool.Info.getMax() | 右寄せ数値 |

## 出力条件

### 抽出条件

| 条件名 | 説明 | 必須 |
|-------|------|-----|
| thread_pool_patterns | スレッドプール名パターン（ワイルドカード対応、デフォルト: "*"） | No |
| local | ローカルクラスタ状態を使用 | No |

### ソート順

| 優先度 | 項目 | 昇順/降順 |
|-------|------|---------|
| 1 | スレッドプール名 | 昇順（TreeMap使用） |

### 改ページ条件

改ページは発生しない。

## データベース参照仕様

### 参照テーブル一覧

| データソース | 用途 | 取得方法 |
|-----------|------|---------|
| ClusterStateResponse | ノード一覧 | ClusterStateRequest（nodes=true） |
| NodesInfoResponse | スレッドプール情報・プロセス情報 | NodesInfoRequest（PROCESS, THREAD_POOL） |
| NodesStatsResponse | スレッドプール統計 | NodesStatsRequest（THREAD_POOL） |

## 計算仕様

### 計算項目一覧

| 項目名 | 計算式 | 端数処理 | 備考 |
|-------|-------|---------|------|
| type 別の表示制御 | FORK_JOIN の場合は統計値を0/-1で固定表示 | なし | fork_join プールは統計を持たない |
| core/max/size | SCALING の場合: core=min, max=max / FIXED の場合: size=max | なし | スレッドプールタイプにより表示項目が異なる |
| queue_size | null の場合は -1 表示 | なし | -1は無制限を意味する |

## 処理フロー

### 出力フロー

```mermaid
flowchart TD
    A[GET /_cat/thread_pool リクエスト受信] --> B[doCatRequest]
    B --> C[ClusterStateRequest 実行]
    C --> D[NodesInfoRequest 実行]
    D --> E[NodesStatsRequest 実行]
    E --> F[buildTable でテーブル構築]
    F --> G[スレッドプール名パターンマッチング]
    G --> H[ノード×スレッドプールの各行を writeRow で出力]
    H --> I[RestTable.buildResponse]
```

## エラー処理

### エラーケース一覧

| エラー種別 | 発生条件 | 表示メッセージ | 対処方法 |
|----------|---------|--------------|---------|
| 統計情報なし | NodeStats がnullの場合 | 各統計カラムがnull表示 | 正常動作 |
| スレッドプール情報なし | NodeInfo がnullの場合 | type等がnull表示 | 正常動作 |

## パフォーマンス要件

| 項目 | 内容 |
|-----|------|
| 想定データ件数 | ノード数 x スレッドプール数（通常数十～数百行） |
| 目標出力時間 | 数百ミリ秒（3段階の内部API呼び出し） |
| 同時出力数上限 | 制限なし |

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

- ノードのPID、ホスト名、IPアドレス等のインフラ情報が含まれる。

## 備考

- スレッドプール名はTreeMapを使用してアルファベット順にソートされる。
- FORK_JOIN タイプのスレッドプールは統計値（active, pool_size, queue等）を0または-1で固定表示し、parallelism カラムのみ有効値を持つ。
- writeRow() メソッドがパッケージプライベートとして公開されており、テストから直接呼び出し可能。

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | RestThreadPoolAction.java | `server/src/main/java/org/opensearch/rest/action/cat/RestThreadPoolAction.java` | 行147-177: getTableWithHeader() で22カラムの定義 |

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | RestThreadPoolAction.java | `server/src/main/java/org/opensearch/rest/action/cat/RestThreadPoolAction.java` | 行96-131: doCatRequest() で3段階の非同期チェーン |

**主要処理フロー**:
1. **行97-103**: ClusterStateRequest でノード一覧取得
2. **行108-111**: NodesInfoRequest で PROCESS + THREAD_POOL 情報取得
3. **行115-117**: NodesStatsRequest で THREAD_POOL 統計取得

#### Step 3: テーブル構築とFORK_JOIN分岐を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | RestThreadPoolAction.java | `server/src/main/java/org/opensearch/rest/action/cat/RestThreadPoolAction.java` | 行180-263: writeRow() でFORK_JOIN分岐ロジック |
| 3-2 | RestThreadPoolAction.java | `server/src/main/java/org/opensearch/rest/action/cat/RestThreadPoolAction.java` | 行265-335: buildTable() でパターンマッチングと行構築 |

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

```
AbstractCatAction.prepareRequest()
    |
    +-- RestThreadPoolAction.doCatRequest() [行96]
           |
           +-- client.admin().cluster().state() [行105]
           |      |
           |      +-- client.admin().cluster().nodesInfo() [行112]
           |             |
           |             +-- client.admin().cluster().nodesStats() [行118]
           |                    |
           |                    +-- buildTable() [行265]
           |                           |
           |                           +-- Regex.simpleMatch() [行281]
           |                           +-- writeRow() [行180]
           |
           +-- RestTable.buildResponse()
```

### データフロー図

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

GET /_cat/thread_pool     --->  ClusterStateRequest         --->  テキストテーブル
/{patterns}                        |                              (ノード数 x プール数)
                                   v
                            ClusterStateResponse (ノード一覧)
                                   |
                            NodesInfoRequest (PROCESS, THREAD_POOL)
                                   |
                                   v
                            NodesInfoResponse (プール設定)
                                   |
                            NodesStatsRequest (THREAD_POOL)
                                   |
                                   v
                            NodesStatsResponse (プール統計)
                                   |
                                   v
                            パターンマッチング → writeRow() → Table
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| RestThreadPoolAction.java | `server/src/main/java/org/opensearch/rest/action/cat/RestThreadPoolAction.java` | ソース | Thread Pool Report メイン処理 |
| RestThreadPoolActionTests.java | `server/src/test/java/org/opensearch/rest/action/cat/RestThreadPoolActionTests.java` | テスト | ユニットテスト |
| RestThreadPoolActionRowTests.java | `server/src/test/java/org/opensearch/rest/action/cat/RestThreadPoolActionRowTests.java` | テスト | writeRow テスト |
| ThreadPool.java | `server/src/main/java/org/opensearch/threadpool/ThreadPool.java` | ソース | スレッドプール定義 |
| ThreadPoolStats.java | `server/src/main/java/org/opensearch/threadpool/ThreadPoolStats.java` | ソース | スレッドプール統計 |
| ThreadPoolInfo.java | `server/src/main/java/org/opensearch/threadpool/ThreadPoolInfo.java` | ソース | スレッドプール情報 |
