# 帳票設計書 30-SparkConnectServerPage

## 概要

本ドキュメントは、Apache Spark Web UI における Spark Connect Server ページ（SparkConnectServerPage）の帳票設計書である。Spark Connect Server のセッション統計とリクエスト実行統計を一覧表示する HTML レポートページの仕様を定義する。

### 本帳票の処理概要

SparkConnectServerPage は Spark Connect Server のダッシュボードとして、サーバの起動時刻・稼働時間・オンラインセッション数・実行中リクエスト数の基本情報、セッション統計テーブル、リクエスト統計テーブルを表示する。

**業務上の目的・背景**：Spark Connect は gRPC ベースのクライアント・サーバ接続プロトコルであり、リモートクライアントから Spark クラスタへのアクセスを提供する。サーバのセッション管理やリクエスト実行状況の監視は、マルチテナント環境での安定運用に不可欠である。本帳票により、Spark Connect Server の稼働状況を一元的に把握できる。

**帳票の利用シーン**：Spark Connect Server 稼働中に「Connect」タブを開き、接続セッションの管理やリクエスト実行状況を確認する際に利用される。マルチテナント環境でのユーザ別利用状況の把握、問題リクエストの特定に使われる。

**主要な出力内容**：
1. 基本統計（Started at、Time since start）
2. オンラインセッション数と実行中リクエスト数
3. Session Statistics テーブル（User、Session ID、Start/Finish Time、Duration、Total Execute）
4. Request Statistics テーブル（User、Job ID、SQL Query ID、Session ID、Start/Finish/Close Time、Execution Time、Duration、Statement、State、Operation ID、Job Tag、Spark Session Tags、Detail）

**帳票の出力タイミング**：Spark Web UI の「Connect」タブにアクセスした際にリアルタイムで生成される。

**帳票の利用者**：Spark Connect Server 運用管理者、プラットフォームエンジニア、データエンジニア

## 帳票種別

Web UI ページ（一覧表）

## 利用画面

| 画面No | 画面名 | URL/ルーティング | 出力操作 |
|--------|--------|-----------------|---------|
| 30 | SparkConnectServerPage | `/connect/` | Spark UI の「Connect」タブをクリック |

## 出力形式

### 基本仕様

| 項目 | 内容 |
|-----|------|
| ファイル形式 | HTML（Web UI ページ） |
| 用紙サイズ | N/A（ブラウザ表示） |
| 向き | N/A |
| ファイル名 | N/A（動的 HTML レスポンス） |
| 出力方法 | ブラウザ上にリアルタイム表示 |
| 文字コード | UTF-8 |

### PDF固有設定

N/A

### Excel固有設定

N/A

## 帳票レイアウト

### レイアウト概要

```
+---------------------------------------------+
|   Spark UI ヘッダー (Spark Connect)            |
+---------------------------------------------+
| Started at: {date}                           |
| Time since start: {duration}                 |
+---------------------------------------------+
| {N} session(s) are online, running           |
| {M} Request(s)                               |
+---------------------------------------------+
| ▼ Session Statistics ({count})               |
| +------------------------------------------+|
| | User | Session ID | Start Time |          ||
| | Finish Time | Duration | Total Execute   ||
| +------------------------------------------+|
+---------------------------------------------+
| ▼ Request Statistics ({count})               |
| +------------------------------------------+|
| | User | Job ID | SQL Query ID | Session ID||
| | Start Time | Finish Time | Close Time    ||
| | Execution Time | Duration | Statement    ||
| | State | Operation ID | Job Tag           ||
| | Spark Session Tags | Detail              ||
| +------------------------------------------+|
+---------------------------------------------+
```

### ヘッダー部

| No | 項目名 | 説明 | データ取得元 | 表示形式 |
|----|-------|------|-------------|---------|
| 1 | Started at | サーバ起動時刻 | parent.startTime | formatDate |
| 2 | Time since start | 稼働時間 | currentTime - startTime | formatDurationVerbose |
| 3 | Online sessions | オンラインセッション数 | store.getOnlineSessionNum | 数値 |
| 4 | Running requests | 実行中リクエスト数 | store.getTotalRunning | 数値 |

### 明細部（Session Statistics）

| No | 項目名 | 説明 | データ取得元 | 表示形式 | 列幅 |
|----|-------|------|-------------|---------|-----|
| 1 | User | ユーザ ID | session.userId | テキスト | auto |
| 2 | Session ID | セッション ID | session.sessionId | リンク（セッション詳細） | auto |
| 3 | Start Time | 開始時刻 | session.startTimestamp | formatDate | auto |
| 4 | Finish Time | 終了時刻 | session.finishTimestamp | formatDate | auto |
| 5 | Duration | セッション時間 | session.totalTime | formatDurationVerbose | auto |
| 6 | Total Execute | 実行リクエスト数 | session.totalExecution | 数値 | auto |

### 明細部（Request Statistics）

| No | 項目名 | 説明 | データ取得元 | 表示形式 | 列幅 |
|----|-------|------|-------------|---------|-----|
| 1 | User | ユーザ ID | info.userId | テキスト | auto |
| 2 | Job ID | Spark ジョブ ID | executionInfo.jobId | ジョブリンク | auto |
| 3 | SQL Query ID | SQL 実行 ID | executionInfo.sqlExecId | SQL リンク | auto |
| 4 | Session ID | セッション ID | info.sessionId | セッションリンク | auto |
| 5 | Start Time | 開始時刻 | info.startTimestamp | formatDate | auto |
| 6 | Finish Time | 終了時刻 | info.finishTimestamp | formatDate | auto |
| 7 | Close Time | クローズ時刻 | info.closeTimestamp | formatDate | auto |
| 8 | Execution Time | 実行時間 | totalTime(finishTimestamp) | formatDurationVerbose | auto |
| 9 | Duration | 全体時間 | totalTime(closeTimestamp) | formatDurationVerbose | auto |
| 10 | Statement | リクエスト内容 | info.statement | テキスト | auto |
| 11 | State | 実行状態 | info.state / isExecutionActive | "RUNNING" / 状態テキスト | auto |
| 12 | Operation ID | オペレーション ID | info.operationId | テキスト | auto |
| 13 | Job Tag | ジョブタグ | info.jobTag | テキスト | auto |
| 14 | Spark Session Tags | セッションタグ一覧 | info.sparkSessionTags | カンマ区切り | auto |
| 15 | Detail | 詳細情報 | info.detail | エラーメッセージ | auto |

### フッター部

| No | 項目名 | 説明 | データ取得元 | 表示形式 |
|----|-------|------|-------------|---------|
| 1 | ページネーション | 各テーブルのページ切り替え | PagedTable 基盤 | ページ番号リンク |

## 出力条件

### 抽出条件

| 条件名 | 説明 | 必須 |
|-------|------|-----|
| {tag}.page | ページ番号 | No（デフォルト: 1） |
| {tag}.sort | ソートカラム名 | No（デフォルト: Start Time） |
| {tag}.desc | 降順フラグ | No |
| {tag}.pageSize | ページサイズ | No |

### ソート順

| 優先度 | 項目 | 昇順/降順 |
|-------|------|---------|
| 1 | Start Time（デフォルト） | 昇順（切替可能） |

### 改ページ条件

PagedTable フレームワークによるページング。

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

### 参照テーブル一覧

| テーブル名 | 用途 | 結合条件 |
|-----------|------|---------|
| SparkConnectServerAppStatusStore | セッション・リクエスト情報の取得 | N/A |

### テーブル別参照項目詳細

#### SparkConnectServerAppStatusStore

| 参照項目（カラム名） | 帳票項目との対応 | 取得条件 | 備考 |
|-------------------|----------------|---------|------|
| getOnlineSessionNum | オンラインセッション数 | - | Int |
| getTotalRunning | 実行中リクエスト数 | - | Int |
| getSessionList | セッション一覧 | - | Seq[SessionInfo] |
| getExecutionList | リクエスト一覧 | - | Seq[ExecutionInfo] |

## 計算仕様

### 計算項目一覧

| 項目名 | 計算式 | 端数処理 | 備考 |
|-------|-------|---------|------|
| Duration (Request) | executionInfo.totalTime(closeTimestamp) | なし | closeTimestamp が 0 の場合 currentTime 使用 |
| Execution Time | executionInfo.totalTime(finishTimestamp) | なし | finishTimestamp が 0 の場合 currentTime 使用 |
| State 表示値 | if (isExecutionActive) "RUNNING" else info.state | N/A | 実行中の場合は常に "RUNNING" |

## 処理フロー

### 出力フロー

```mermaid
flowchart TD
    A[HTTPリクエスト受信] --> B[store.synchronized でデータ取得]
    B --> C[基本統計生成]
    C --> D[セッション統計テーブル生成]
    D --> E[リクエスト統計テーブル生成]
    E --> F[headerSparkPage で HTML 生成]
    F --> G[レスポンス返却]
```

## エラー処理

### エラーケース一覧

| エラー種別 | 発生条件 | 表示メッセージ | 対処方法 |
|----------|---------|--------------|---------|
| テーブル描画エラー | IllegalArgumentException / IndexOutOfBoundsException | "Error while rendering job table: {exception}" | パラメータを修正する |
| データなし | セッション・リクエストが空 | "No statistics have been generated yet." | クライアントが接続するまで待つ |

## パフォーマンス要件

| 項目 | 内容 |
|-----|------|
| 想定データ件数 | セッション数十～数百、リクエスト数百～数千 |
| 目標出力時間 | 1秒以内 |
| 同時出力数上限 | Spark Web UI のスレッドプール制約に従う |

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

- Statement にはクエリ文が含まれるため、アクセス制御を適切に設定すること。
- User ID、Session ID、Operation ID 等の識別情報が表示される。
- store.synchronized でスレッドセーフにデータ取得される。
- Job Tag と Spark Session Tags はマルチテナント環境でのリソース追跡に使用される。

## 備考

- Spark Connect Server のページ構造は ThriftServer（No.28）と類似しているが、以下の相違点がある：
  - ThriftServer は userName / ip フィールドだが、Connect は userId フィールド
  - Connect には SQL Query ID、Session ID（リンク）、Operation ID、Job Tag、Spark Session Tags の追加列がある
  - Connect では isExecutionActive フラグに基づき State を "RUNNING" にオーバーライドする
- Session ID リンクから SparkConnectServerSessionPage へ遷移できる。
- SQL Query ID リンクから SQL Execution 詳細ページへ遷移できる。
- showSessionLink パラメータでメインページ（true）とセッション詳細ページ（false）でのSession ID列の表示を制御する。

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | SessionInfo | `sql/connect/server/src/main/scala/org/apache/spark/sql/connect/ui/SparkConnectServerAppStatusStore.scala` | userId, sessionId, startTimestamp, finishTimestamp, totalTime, totalExecution |
| 1-2 | ExecutionInfo | `sql/connect/server/src/main/scala/org/apache/spark/sql/connect/ui/SparkConnectServerAppStatusStore.scala` | userId, sessionId, statement, state, operationId, jobTag, sparkSessionTags, jobId, sqlExecId, isExecutionActive |
| 1-3 | SqlStatsTableRow | `sql/connect/server/src/main/scala/org/apache/spark/sql/connect/ui/SparkConnectServerPage.scala` | jobTag, jobId, sqlExecId, duration, executionTime, sparkSessionTags, executionInfo（行422-429） |

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | SparkConnectServerTab.scala | `sql/connect/server/src/main/scala/org/apache/spark/sql/connect/ui/SparkConnectServerTab.scala` | ページ登録（行43-44）、prefix "connect" |
| 2-2 | SparkConnectServerPage.scala | `sql/connect/server/src/main/scala/org/apache/spark/sql/connect/ui/SparkConnectServerPage.scala` | render() メソッド（行42-57） |

**主要処理フロー**:
1. **行43**: store.synchronized でデータ一貫性を保証
2. **行44**: generateBasicStats() で基本情報生成
3. **行47-51**: オンラインセッション数・実行中リクエスト数の表示
4. **行53**: generateSessionStatsTable でセッションテーブル生成
5. **行54**: generateSQLStatsTable でリクエストテーブル生成
6. **行56**: headerSparkPage で最終 HTML 生成

#### Step 3: テーブル描画を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | SparkConnectServerPage.scala | `sql/connect/server/src/main/scala/org/apache/spark/sql/connect/ui/SparkConnectServerPage.scala` | SqlStatsPagedTable クラス（行170-341）- showSessionLink パラメータによる列制御 |
| 3-2 | SparkConnectServerPage.scala | `sql/connect/server/src/main/scala/org/apache/spark/sql/connect/ui/SparkConnectServerPage.scala` | SessionStatsPagedTable クラス（行343-420） |
| 3-3 | SparkConnectServerPage.scala | `sql/connect/server/src/main/scala/org/apache/spark/sql/connect/ui/SparkConnectServerPage.scala` | SqlStatsTableDataSource（行431-491）, SessionStatsTableDataSource（行493-526） |

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

```
SparkUI
    |
    +-- SparkConnectServerTab (SparkUITab, prefix="connect")
           |
           +-- SparkConnectServerPage (WebUIPage, prefix="")
           |      |
           |      +-- render(request) [store.synchronized]
           |             +-- generateBasicStats()
           |             +-- store.getOnlineSessionNum
           |             +-- store.getTotalRunning
           |             +-- generateSessionStatsTable()
           |             |      +-- SessionStatsPagedTable
           |             |             +-- SessionStatsTableDataSource
           |             +-- generateSQLStatsTable()
           |                    +-- SqlStatsPagedTable (showSessionLink=true)
           |                           +-- SqlStatsTableDataSource
           |
           +-- SparkConnectServerSessionPage
                  |
                  +-- render(request) [store.synchronized]
                         +-- store.getSession(sessionId)
                         +-- generateBasicStats(sessionId)
                         +-- generateSQLStatsTable(request, sessionId)
                                +-- SqlStatsPagedTable (showSessionLink=false)
```

### データフロー図

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

HTTPリクエスト                     render()
                              --> store.synchronized          --> HTML レスポンス
                                   |                            (基本情報 +
SparkConnectServerAppStatusStore   |                             Session テーブル +
(インメモリ)                  --> getSessionList                  Request テーブル)
                                   getExecutionList
                                   getOnlineSessionNum
                                   getTotalRunning
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| SparkConnectServerPage.scala | `sql/connect/server/src/main/scala/org/apache/spark/sql/connect/ui/SparkConnectServerPage.scala` | ソース | メインページクラス |
| SparkConnectServerTab.scala | `sql/connect/server/src/main/scala/org/apache/spark/sql/connect/ui/SparkConnectServerTab.scala` | ソース | タブ登録 |
| SparkConnectServerAppStatusStore.scala | `sql/connect/server/src/main/scala/org/apache/spark/sql/connect/ui/SparkConnectServerAppStatusStore.scala` | ソース | データストア |
| SparkConnectServerSessionPage.scala | `sql/connect/server/src/main/scala/org/apache/spark/sql/connect/ui/SparkConnectServerSessionPage.scala` | ソース | セッション詳細ページ |
| ToolTips.scala | `sql/connect/server/src/main/scala/org/apache/spark/sql/connect/ui/ToolTips.scala` | ソース | ツールチップ文言定義 |
