# 画面設計書 16-Streaming Query List（ストリーミングクエリ一覧）

## 概要

本ドキュメントは、Apache Spark Application UIのStructured Streamingタブにあるストリーミングクエリ一覧画面の設計内容を記述する。本画面はActive/Inactiveなストリーミングクエリを一覧テーブル形式で表示する。

### 本画面の処理概要

**業務上の目的・背景**：Spark Structured Streamingを使用したリアルタイムデータ処理において、実行中および完了済みのストリーミングクエリの状態を一元管理する画面である。運用者はアクティブなクエリの入力レート・処理レートを把握し、異常な遅延やエラーの発生を早期に検知できる。また、非アクティブなクエリの終了理由（エラーメッセージ）を確認することで、障害対応の迅速化を図ることができる。

**画面へのアクセス方法**：SparkUIのタブバーにある「Structured Streaming」タブをクリックすることでアクセスする。Structured Streamingを使用しているアプリケーションでのみタブが表示される。

**主要な操作・処理内容**：
1. Active Streaming Queriesセクションでアクティブなクエリ一覧を確認する
2. Completed Streaming Queriesセクションで完了・停止したクエリ一覧を確認する
3. Run IDリンクをクリックしてストリーミングクエリ統計画面（No.17）へ遷移する
4. ページングテーブルでページ切り替え・ソートを行う
5. 非アクティブクエリのエラーメッセージを確認する

**画面遷移**：SparkUIのタブバーから直接アクセスする。本画面からストリーミングクエリ統計画面（No.17）へ遷移可能。

**権限による表示制御**：Structured Streamingモジュール未使用の場合、タブ自体が表示されない。ACL設定が有効な場合、閲覧権限が必要。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 17 | Spark Web UI | 主機能 | Active/Inactiveなストリーミングクエリを一覧テーブル表示する主処理 |
| 36 | ストリーム処理エンジン | 主機能 | StreamingQueryStoreからクエリのステータス・入力レート・処理レート情報を取得して表示 |
| 95 | KVStore | API連携 | StreamingQueryStatusStore経由でストリーミングクエリデータを非同期取得 |

## 画面種別

一覧

## URL/ルーティング

- パス: `/StreamingQuery/`
- パラメータ（ページング・ソート用）:
  - `{tag}.page` - ページ番号（tag: active/completed）
  - `{tag}.sort` - ソートカラム
  - `{tag}.desc` - 降順フラグ
  - `{tag}.pageSize` - ページサイズ
- 例: `/StreamingQuery/?active.page=1&active.sort=Start+Time`

## 入出力項目

| 項目名 | 入出力 | 型 | 必須 | 説明 |
|--------|--------|------|------|------|
| {tag}.page | 入力（URLパラメータ） | Int | 任意 | ページ番号。デフォルト: 1 |
| {tag}.sort | 入力（URLパラメータ） | String | 任意 | ソートカラム。デフォルト: "Start Time" |
| {tag}.desc | 入力（URLパラメータ） | Boolean | 任意 | 降順フラグ |
| {tag}.pageSize | 入力（URLパラメータ） | Int | 任意 | ページサイズ |

## 表示項目

### Streaming Queryテーブル（Active/Completed共通）

| 項目名 | データ型 | 説明 | ソート |
|--------|----------|------|--------|
| Name | String | クエリ名 | 可 |
| Status | String | クエリの状態（RUNNING/FINISHED等） | 可 |
| ID | UUID | クエリの一意識別子 | 可 |
| Run ID | UUID | 実行ラン識別子（統計画面へのリンク） | 可 |
| Start Time | Timestamp | クエリ開始日時 | 可 |
| Duration | Long | 経過時間（アクティブ:現在-開始、非アクティブ:最終進捗-開始） | 可 |
| Avg Input /sec | Double | 平均入力レート（records/sec） | 可 |
| Avg Process /sec | Double | 平均処理レート（records/sec） | 可 |
| Latest Batch | Long | 最新バッチID | 可 |
| Error | String | エラーメッセージ（Completedテーブルのみ） | 不可 |

## イベント仕様

### 1-Run IDリンククリック

Run ID列のリンクをクリックすると、ストリーミングクエリ統計画面（/StreamingQuery/statistics/?id={runId}）へ遷移する。

### 2-ページ切り替え

ページングテーブルのページナビゲーションリンクをクリックすると、対象セクションのページが切り替わる。

### 3-ソート切り替え

テーブルヘッダのカラムをクリックすると、該当カラムでソートが切り替わる。

### 4-セクション折りたたみ

Active/Completedの各セクションヘッダをクリックすると、該当セクションのテーブルが折りたたみ/展開される。

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

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

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| ページ表示 | - | SELECT | StreamingQueryStatusStore.allQueryUIDataでストリーミングクエリデータを取得 |

本画面はデータベースへの更新操作を行わない。

## メッセージ仕様

| メッセージID | 種別 | メッセージ内容 | 表示条件 |
|-------------|------|--------------|----------|
| MSG-001 | エラー | "Error while rendering execution table: {exception}" | テーブルのレンダリング中に例外が発生した場合 |

## 例外処理

- ページングパラメータの不正値: IllegalArgumentExceptionまたはIndexOutOfBoundsExceptionをキャッチし、エラーメッセージをテーブル内に表示
- ストリーミングクエリデータなし: 各セクション（Active/Completed）のデータが空の場合、該当セクションは表示されない
- 進捗データなし: NaN表示となる（withNoProgressヘルパー関数で制御）

## 備考

- StreamingQueryTabのデフォルト画面として表示される
- displayOrderは2（タブの表示順序）
- 平均入力レートと平均処理レートはrecentProgressの全エントリの平均値
- 進捗データがないクエリは"NaN"と表示される
- ページタイトルは「Streaming Query」

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | StreamingQueryUIData | `sql/core/src/main/scala/org/apache/spark/sql/streaming/ui/StreamingQueryUIData.scala` | StreamingQueryUIDataクラスのフィールド（summary, recentProgress, lastProgress）を確認 |
| 1-2 | StructuredStreamingRow | `sql/core/src/main/scala/org/apache/spark/sql/streaming/ui/StreamingQueryPage.scala` | 行203-207: テーブル行データケースクラス（duration, avgInput, avgProcess, streamingUIData） |

**読解のコツ**: StreamingQueryUIDataはsummary（StreamingQueryStatus）とrecentProgress（Array[StreamingQueryProgress]）を保持する。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | StreamingQueryTab.scala | `sql/core/src/main/scala/org/apache/spark/sql/streaming/ui/StreamingQueryTab.scala` | 行23-38: StreamingQueryTabクラス定義。StreamingQueryPageとStreamingQueryStatisticsPageを登録 |
| 2-2 | StreamingQueryPage.scala | `sql/core/src/main/scala/org/apache/spark/sql/streaming/ui/StreamingQueryPage.scala` | 行33-34: クラス定義。WebUIPage("")でデフォルトページ |

**主要処理フロー**:
1. **行36-38**: renderメソッドでgenerateStreamingQueryTableを呼び出し
2. **行41-43**: parent.store.allQueryUIDataでデータ取得し、Active/Inactiveに分割
3. **行47-63**: Active Queriesセクション生成
4. **行65-81**: Completed Queriesセクション生成

#### Step 3: ページングテーブルを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | StreamingQueryPage.scala | `sql/core/src/main/scala/org/apache/spark/sql/streaming/ui/StreamingQueryPage.scala` | 行113-201: StreamingQueryPagedTableクラス。ヘッダ定義、行レンダリング |
| 3-2 | StreamingQueryPage.scala | `sql/core/src/main/scala/org/apache/spark/sql/streaming/ui/StreamingQueryPage.scala` | 行209-261: StreamingQueryDataSourceクラス。ソートとスライス |

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

```
StreamingQueryTab [行23]
    |
    +-- StreamingQueryPage (WebUIPage("")) [行31]
            |
            +-- render(request) [行36]
                    |
                    +-- generateStreamingQueryTable(request) [行37]
                            |
                            +-- parent.store.allQueryUIData [行43]
                            |       |
                            |       +-- StreamingQueryStatusStore
                            |
                            +-- partition(_.summary.isActive) [行43]
                            |
                            +-- queryTable(activeQueries, request, "active") [行59]
                            |       |
                            |       +-- StreamingQueryPagedTable [行92-100]
                            |               |
                            |               +-- StreamingQueryDataSource [行148]
                            |               +-- headers / row メソッド
                            |
                            +-- queryTable(inactiveQueries, request, "completed") [行76]
```

### データフロー図

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

URLパラメータ ────────────> StreamingQueryPage.render()
(page, sort, desc,                 |
 pageSize)                         +---> StreamingQueryStatusStore
                                   |     .allQueryUIData ──────────> Seq[StreamingQueryUIData]
                                   |           |
                                   +---> Active/Inactive分割
                                   |           |
                                   +---> StreamingQueryPagedTable
                                   |     (ソート・ページング)
                                   |           |
                                   +---> テーブルHTML ─────────────> 完成ページHTML
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| StreamingQueryPage.scala | `sql/core/src/main/scala/org/apache/spark/sql/streaming/ui/StreamingQueryPage.scala` | ソース | メイン画面ページクラス・テーブルクラス |
| StreamingQueryTab.scala | `sql/core/src/main/scala/org/apache/spark/sql/streaming/ui/StreamingQueryTab.scala` | ソース | タブ定義・ページ登録 |
| StreamingQueryUIData.scala | `sql/core/src/main/scala/org/apache/spark/sql/streaming/ui/StreamingQueryUIData.scala` | ソース | クエリUIデータモデル |
| StreamingQueryStatusStore.scala | `sql/core/src/main/scala/org/apache/spark/sql/execution/ui/StreamingQueryStatusStore.scala` | ソース | クエリステータスストア |
| UIUtils.scala (streaming) | `sql/core/src/main/scala/org/apache/spark/sql/streaming/ui/UIUtils.scala` | ソース | Streaming固有UIユーティリティ |
| PagedTable.scala | `core/src/main/scala/org/apache/spark/ui/PagedTable.scala` | ソース | ページングテーブル基底クラス |
