# 画面設計書 30-JobManagerプロファイラ

## 概要

本ドキュメントは、Apache Flink Web Dashboardの「JobManagerプロファイラ」画面の設計仕様を記載したものである。この画面は、JobManagerプロセスのCPUプロファイリングを実行・管理し、パフォーマンス分析を支援する。

### 本画面の処理概要

**業務上の目的・背景**：Flinkクラスターのパフォーマンス最適化において、JobManagerのCPU使用状況を詳細に分析することが重要である。本画面では、async-profilerを使用したプロファイリング機能を提供し、CPUホットスポットの特定、ロック競合の分析、メモリ割り当てのトレース等を可能にする。これにより、開発者やシステム管理者は、JobManagerのパフォーマンスボトルネックを効率的に特定できる。

**画面へのアクセス方法**：グローバルナビゲーションから「Job Manager」を選択後、「Profiler」タブをクリック、または直接 `/job-manager/profiler` にアクセスする。

**主要な操作・処理内容**：
1. プロファイリングインスタンスの作成（Duration、Mode指定）
2. 実行中・完了済みプロファイリング一覧の表示
3. プロファイリング結果のダウンロード
4. プロファイリング一覧の自動リフレッシュ

**画面遷移**：
- 遷移元：JobManagerコンテナ画面のタブナビゲーション
- 同階層：Metrics、Configuration、Logs、Stdout、Log List、Thread Dumpタブと相互遷移可能

**権限による表示制御**：プロファイラ機能は設定 `rest.profiling.enabled: true` で有効化されている必要がある。無効の場合は警告メッセージが表示され、プロファイリング作成ボタンが無効化される。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 32 | REST API | 主機能 | プロファイリング情報の取得（/jobmanager/profiler API） |
| 57 | メトリクスコア | 補助機能 | プロファイリングインスタンスの作成・結果取得 |

## 画面種別

一覧 + 登録（プロファイリング管理）

## URL/ルーティング

- パス: `/job-manager/profiler`
- パラメータ: なし

## 入出力項目

| 項目名 | 項目ID | 入力/出力 | データ型 | 必須 | 説明 |
|--------|--------|----------|---------|------|------|
| プロファイリング時間 | duration | 入力 | number | Yes | プロファイリング実行時間（秒） |
| プロファイリングモード | selectMode | 入力 | string | Yes | CPU/LOCK/WALL/ALLOC/ITIMER |
| プロファイリング一覧 | profilingList | 出力 | ProfilingDetail[] | - | プロファイリング履歴の配列 |
| ローディング状態 | isLoading | 出力 | boolean | - | データ取得中フラグ |
| 作成中状態 | isCreating | 出力 | boolean | - | プロファイリング作成中フラグ |
| 有効状態 | isEnabled | 出力 | boolean | - | 機能有効フラグ |

## 表示項目

| 項目名 | 表示位置 | データソース | 書式 | 説明 |
|--------|----------|-------------|------|------|
| Duration入力 | フォーム | ローカル | 数値入力 | プロファイリング時間（秒単位） |
| Mode選択 | フォーム | ローカル | セレクトボックス | CPU/Lock/Wall-Clock/Allocation/ITIMER |
| 作成ボタン | フォーム | ローカル | ボタン | "Create Profiling Instance" |
| 機能無効警告 | フォーム下 | ローカル | アラート | rest.profiling.enabled: true 設定が必要 |
| Index | テーブル1列目 | ローカル | 数値 | プロファイリングのインデックス |
| Trigger Time | テーブル2列目 | API | 日時 | 開始時刻 |
| Finished Time | テーブル3列目 | API | 日時 | 完了時刻 |
| Profiling Duration | テーブル4列目 | API | 数値 + "s" | 実行時間 |
| Mode | テーブル5列目 | API | テキスト | プロファイリングモード |
| Status | テーブル6列目 | API | テキスト | RUNNING/FINISHED/FAILED |
| Link | テーブル7列目 | API | リンク | 結果ファイルへのリンク |
| Message | テーブル8列目 | API | テキスト | 補足メッセージ |

## イベント仕様

### 1-初期化処理

コンポーネント初期化時（ngOnInit）に実行される。

- **トリガー**: コンポーネントマウント
- **処理内容**:
  1. StatusService.refresh$ をサブスクライブ
  2. loadProfilingList() でプロファイリング一覧を取得
  3. isEnabled を true に設定
- **後続処理**: 画面の初期表示

### 2-プロファイリング作成

「Create Profiling Instance」ボタンをクリックした際に発火する。

- **トリガー**: 作成ボタンクリック（createProfilingInstance()）
- **処理内容**:
  1. 実行中プロファイリングの存在チェック
  2. isCreating を true に設定
  3. createProfilingInstance(selectMode, duration) でAPI呼び出し
  4. 成功時、profilingList の先頭に追加
  5. isCreating を false に設定
- **後続処理**: テーブルの更新

### 3-結果ダウンロード

結果ファイルリンクをクリックした際に発火する。

- **トリガー**: リンククリック（downloadProfilingResult(filePath)）
- **処理内容**:
  1. isLoading を true に設定
  2. loadProfilingResult(filePath) でAPI呼び出し
  3. anchor要素を生成してダウンロード実行
  4. isLoading を false に設定
- **後続処理**: ファイルダウンロード開始

### 4-自動リフレッシュ

StatusServiceの refresh$ によるポーリング更新。

- **トリガー**: statusService.refresh$ のイベント発火
- **処理内容**:
  1. loadProfilingList() でプロファイリング一覧を再取得
  2. profilingList を更新
- **後続処理**: テーブルの再レンダリング

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

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

本画面はプロファイリング操作を行うが、フロントエンドからはREST APIを呼び出すのみで、直接のデータベース操作は発生しない。

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| プロファイリング作成 | - | POST | バックエンドでプロファイリングインスタンスを作成 |

## メッセージ仕様

| メッセージID | 種別 | メッセージ内容 | 表示条件 |
|-------------|------|--------------|----------|
| MSG-001 | 警告 | "Please wait for last profiling finished." | 実行中のプロファイリングが存在する状態で作成を試みた場合 |
| MSG-002 | 警告 | "Please set the config `rest.profiling.enabled: true` to enable this experimental profiler feature." | プロファイラ機能が無効の場合 |

## 例外処理

| 例外条件 | 処理内容 |
|---------|---------|
| プロファイリング一覧取得失敗 | isLoading を false に設定、サブスクリプションを解除 |
| プロファイリング作成失敗 | isCreating を false に設定 |
| 結果ダウンロード失敗 | isLoading を false に設定（complete で処理） |

## 備考

- async-profiler を使用したプロファイリング機能（実験的機能）
- プロファイリングモード:
  - CPU: Java・ネイティブ・JVM・カーネル関数を含むスタックトレース
  - Lock: ロック/モニターの競合分析（待機時間をナノ秒単位で計測）
  - Wall-Clock: 全スレッドを均等にサンプリング（起動時間分析に有用）
  - Allocation: ヒープ割り当ての分析（TLABベース）
  - ITIMER: perf_events不要のCPUプロファイリング（カーネルスタック無し）
- デフォルト設定: duration=30秒、mode=ITIMER

---

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

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

### 推奨読解順序

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

プロファイリング情報のインターフェースを理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | job-profiler.ts | `flink-runtime-web/web-dashboard/src/app/interfaces/job-profiler.ts` | ProfilingList, ProfilingDetail インターフェース |

**読解のコツ**: ProfilingDetail は status, triggerTime, finishedTime, duration, message, outputFile, mode を持つ。

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

メインコンポーネントの実装を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | job-manager-profiler.component.ts | `flink-runtime-web/web-dashboard/src/app/pages/job-manager/profiler/job-manager-profiler.component.ts` | プロファイリング管理ロジック |

**主要処理フロー**:
1. **61-66行目**: メンバー変数定義（profilingList, isLoading, isCreating, duration, selectMode, isEnabled）
2. **75-92行目**: createProfilingInstance() - プロファイリング作成
3. **94-118行目**: ngOnInit() - 初期化と自動リフレッシュ設定
4. **121-137行目**: downloadProfilingResult() - 結果ダウンロード

#### Step 3: テンプレートを理解する

HTMLテンプレートの構造を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | job-manager-profiler.component.html | `flink-runtime-web/web-dashboard/src/app/pages/job-manager/profiler/job-manager-profiler.component.html` | フォームとテーブル |

**主要処理フロー**:
- **17-31行目**: Duration入力（nz-input-number）
- **34-84行目**: Mode選択（nz-select）とツールチップ説明
- **88-97行目**: 作成ボタンと情報アイコン
- **123-129行目**: 機能無効警告（nz-alert）
- **131-164行目**: プロファイリング一覧テーブル

#### Step 4: サービス層を理解する

REST API呼び出しを行うサービスを理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | job-manager.service.ts | `flink-runtime-web/web-dashboard/src/app/services/job-manager.service.ts` | loadProfilingList, createProfilingInstance, loadProfilingResult メソッド |

**主要処理フロー**:
- **130-132行目**: loadProfilingList() - /jobmanager/profiler API (GET)
- **134-137行目**: createProfilingInstance() - /jobmanager/profiler API (POST)
- **139-151行目**: loadProfilingResult() - /jobmanager/profiler/{filePath} API

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

```
JobManagerProfilerComponent
    │
    ├─ ngOnInit()
    │      │
    │      └─ StatusService.refresh$ (サブスクライブ)
    │             │
    │             └─ JobManagerService.loadProfilingList()
    │                    └─ HTTP GET /jobmanager/profiler
    │
    ├─ createProfilingInstance()
    │      │
    │      ├─ 実行中チェック (profilingList[0].status === 'RUNNING')
    │      │
    │      └─ JobManagerService.createProfilingInstance(mode, duration)
    │             └─ HTTP POST /jobmanager/profiler
    │
    └─ downloadProfilingResult(filePath)
           │
           └─ JobManagerService.loadProfilingResult(filePath)
                  └─ HTTP GET /jobmanager/profiler/{filePath}
```

### データフロー図

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

Duration (30) ─────┐
                   │
Mode (ITIMER) ────┼──▶ createProfilingInstance() ──▶ profilingList 更新
                   │              │
作成ボタン ────────┘              ▼
                           HTTP POST /jobmanager/profiler
                                  │
                                  ▼
                           ProfilingDetail
                                  │
                                  ▼
                    ┌─────────────┴─────────────┐
                    ▼                           ▼
             テーブル表示              結果リンク表示
                                               │
                                               ▼
                                    downloadProfilingResult()
                                               │
                                               ▼
                                    ファイルダウンロード
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| job-manager-profiler.component.ts | `flink-runtime-web/web-dashboard/src/app/pages/job-manager/profiler/job-manager-profiler.component.ts` | ソース | メインコンポーネント |
| job-manager-profiler.component.html | `flink-runtime-web/web-dashboard/src/app/pages/job-manager/profiler/job-manager-profiler.component.html` | テンプレート | UI構造定義 |
| job-manager-profiler.component.less | `flink-runtime-web/web-dashboard/src/app/pages/job-manager/profiler/job-manager-profiler.component.less` | スタイル | コンポーネント固有スタイル |
| job-manager.service.ts | `flink-runtime-web/web-dashboard/src/app/services/job-manager.service.ts` | ソース | API呼び出しサービス |
| job-profiler.ts | `flink-runtime-web/web-dashboard/src/app/interfaces/job-profiler.ts` | ソース | データ型定義 |
| status.service.ts | `flink-runtime-web/web-dashboard/src/app/services/status.service.ts` | ソース | 自動リフレッシュサービス |
