# バッチ設計書 23-native-cli-pgo-instrument

## 概要

本ドキュメントは、clojure-lspプロジェクトにおけるPGO（Profile-Guided Optimization）プロファイル収集用ネイティブイメージ生成バッチ（native-cli-pgo-instrument）の設計を記載したものである。

### 本バッチの処理概要

本バッチは、GraalVMのPGO機能を活用するためのプロファイル収集用ネイティブイメージを生成する処理である。生成されたイメージを実際のワークロードで実行することで、実行時の振る舞いを収集し、その情報を使って最終的なネイティブイメージを最適化する。

**業務上の目的・背景**：GraalVMのPGO（Profile-Guided Optimization）は、実際の実行パターンに基づいてネイティブイメージを最適化する技術である。プロファイルデータを収集するために、まず計測機能（instrumentation）を有効にしたネイティブイメージを生成し、それを使用してプロファイルを収集する。収集されたプロファイル（.iprof ファイル）は、native-cliバッチで使用され、より高速なネイティブイメージの生成に活用される。これにより、実際の使用パターンに最適化された高性能なバイナリを配布できる。

**バッチの実行タイミング**：パフォーマンス最適化のためのプロファイル更新が必要な場合に、開発者が手動で実行する。通常のリリースサイクルでは頻繁に実行されない。

**主要な処理内容**：
1. native-cli関数を `--pgo-instrument` オプション付きで呼び出し
2. PGOプロファイル収集用フラグの設定
3. 計測機能付きネイティブイメージの生成
4. 生成されたイメージをプロジェクトルートへ移動

**前後の処理との関連**：生成されたイメージを実行してプロファイルを収集した後、収集された .iprof ファイルは `cli/graalvm/default.iprof` に保存される。このファイルはnative-cliバッチで `--pgo` オプションとして使用される。

**影響範囲**：プロジェクトルートディレクトリに計測機能付きのclojure-lsp（Unix）またはclojure-lsp.exe（Windows）ファイルが生成される。既存ファイルは上書きされる。

## バッチ種別

ビルド処理 / パフォーマンス最適化

## 実行スケジュール

| 項目 | 内容 |
|-----|------|
| 実行頻度 | 随時（パフォーマンスチューニング時） |
| 実行時刻 | 指定なし |
| 実行曜日 | 指定なし |
| 実行日 | 指定なし |
| トリガー | 手動（bb native-cli-pgo-instrument） |

## 実行条件

### 前提条件

| 条件 | 説明 |
|-----|------|
| GRAALVM_HOME | GraalVMのインストールディレクトリを指す環境変数が設定されていること |
| native-image | GraalVMにnative-imageコンポーネントがインストールされていること |
| JDK | Java Development Kit がインストールされていること（JAR生成用） |
| Babashka | bb コマンドが利用可能であること |
| メモリ | 最低8GBのRAMが利用可能であること |

### 実行可否判定

GRAALVM_HOME環境変数が設定されていない場合、"Set GRAALVM_HOME env" メッセージを出力して処理を中断する。

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | デフォルト値 | 説明 |
|-------------|-----|-----|-------------|------|
| GRAALVM_HOME | 環境変数 | Yes | なし | GraalVMインストールディレクトリ |
| CLOJURE_LSP_JAR | 環境変数 | No | なし | 事前ビルド済みJARのパス |
| CLOJURE_LSP_XMX | 環境変数 | No | -J-Xmx8g | ビルド時の最大ヒープサイズ |

### 入力データソース

| データソース | 形式 | 説明 |
|-------------|------|------|
| cli/target/clojure-lsp-standalone.jar | JAR | ネイティブイメージ化対象のuberjar |

## 出力仕様

### 出力データ

| 出力先 | 形式 | 説明 |
|-------|------|------|
| clojure-lsp | ネイティブ実行ファイル | 計測機能付きUnix用ネイティブバイナリ |
| clojure-lsp.exe | ネイティブ実行ファイル | 計測機能付きWindows用ネイティブバイナリ |

### 出力ファイル仕様

| 項目 | 内容 |
|-----|------|
| ファイル名 | clojure-lsp（Unix）/ clojure-lsp.exe（Windows） |
| 出力先 | プロジェクトルートディレクトリ |
| 文字コード | N/A（バイナリ） |
| 区切り文字 | N/A |

## 処理フロー

### 処理シーケンス

```
1. native-cli-pgo-instrument関数呼び出し
   └─ pgo-instrument: trueフラグを設定
   └─ extra-args: ["--pgo-instrument"]を設定

2. native-cli関数への委譲
   └─ native-cli関数が呼び出される
   └─ pgo-instrumentフラグにより、--pgoオプションがスキップされる

3. native-imageコマンド構築
   └─ --pgo-instrumentオプションが追加される
   └─ --pgo=graalvm/default.iprofオプションは追加されない

4. native-imageコマンド実行
   └─ 計測機能付きネイティブイメージを生成

5. ファイル移動
   └─ cli/clojure-lsp[.exe]をプロジェクトルートに移動
```

### フローチャート

```mermaid
flowchart TD
    A[バッチ開始] --> B[pgo-instrumentフラグ設定]
    B --> C[native-cli関数呼び出し]
    C --> D{GRAALVM_HOME設定?}
    D -->|No| E[エラーメッセージ出力]
    E --> F[処理終了]
    D -->|Yes| G[prod-jarでJAR生成]
    G --> H[native-imageコマンド構築]
    H --> I[--pgo-instrumentオプション追加]
    I --> J[native-image実行]
    J --> K{終了コード = 0?}
    K -->|No| L[同じ終了コードで終了]
    K -->|Yes| M[バイナリをルートに移動]
    M --> N[バッチ終了]
```

## データベース操作仕様

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

本バッチはデータベースを使用しない。

| 処理 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| N/A | N/A | N/A | N/A |

### テーブル別操作詳細

該当なし。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | 環境変数未設定 | GRAALVM_HOMEが未設定 | GraalVMをインストールしGRAALVM_HOMEを設定 |
| 1+ | native-imageエラー | コンパイルエラー、リンクエラー | エラーメッセージを確認し対処 |
| - | メモリ不足 | ビルド時のヒープ不足 | CLOJURE_LSP_XMXで増加 |

### リトライ仕様

| 項目 | 内容 |
|-----|------|
| リトライ回数 | 0（自動リトライなし） |
| リトライ間隔 | N/A |
| リトライ対象エラー | N/A |

### 障害時対応

1. native-cliバッチと同様の対処を行う
2. メモリ不足の場合は CLOJURE_LSP_XMX=-J-Xmx16g 等で増加
3. GraalVMのバージョンを確認し、PGO機能がサポートされているか確認

## トランザクション仕様

| 項目 | 内容 |
|-----|------|
| トランザクション範囲 | N/A（ファイルシステム操作のみ） |
| コミットタイミング | N/A |
| ロールバック条件 | N/A |

## パフォーマンス要件

| 項目 | 内容 |
|-----|------|
| 想定処理件数 | 1回の実行で1つのネイティブバイナリを生成 |
| 目標処理時間 | 10〜30分（環境依存） |
| メモリ使用量上限 | 8GB（デフォルト、CLOJURE_LSP_XMXで調整可能） |

## 排他制御

同一プロジェクトディレクトリでの同時実行は想定されていない。

## ログ出力

| ログ種別 | 出力タイミング | 出力内容 |
|---------|--------------|---------|
| 開始ログ | バッチ開始時 | "Building native image..." |
| 進捗ログ | native-image実行中 | GraalVMからの詳細出力（--verbose） |
| 終了ログ | バッチ終了時 | 正常終了時は出力なし |
| エラーログ | 環境変数未設定時 | "Set GRAALVM_HOME env" |

## 監視・アラート

| 監視項目 | 閾値 | アラート先 |
|---------|-----|----------|
| 処理時間 | 60分 | CI/CDシステム |
| 終了コード | 0以外 | CI/CDシステム |

## 備考

- PGOワークフロー：
  1. `bb native-cli-pgo-instrument` で計測用イメージを生成
  2. 生成されたイメージで実際のワークロードを実行（プロファイル収集）
  3. 生成された .iprof ファイルを `cli/graalvm/default.iprof` に配置
  4. `bb native-cli` で最適化されたイメージを生成
- 計測用イメージは通常のイメージより実行速度が遅い（オーバーヘッドあり）
- プロファイル収集には代表的なユースケースを実行することが重要
- native-cliとの違い：
  - `--pgo-instrument` オプションが追加される
  - `--pgo=graalvm/default.iprof` オプションが適用されない
