# 通知設計書 13-レンダラーヘルス通知

## 概要

本ドキュメントは、Ghosttyターミナルエミュレーターにおける「レンダラーヘルス通知」機能の設計を記載するものである。レンダリングエンジンの健全性状態が変化した際に、アプリケーションランタイムに通知を送信し、適切なUI表示やユーザーへの警告を行う機能について詳述する。

### 本通知の処理概要

**業務上の目的・背景**：レンダラーヘルス通知は、ターミナルのレンダリングに問題が発生した場合にユーザーに警告を表示するために実装されている。GPUリソースの枯渇、グラフィックスドライバの問題、フレームレンダリングの失敗など、描画に関する異常を検出した場合に、ユーザーが問題を認識し対処できるようにする。これにより、ユーザーは表示の乱れや遅延の原因を理解し、必要に応じてアプリケーションの再起動や設定変更を検討できる。

**通知の送信タイミング**：レンダラーの健全性状態（Health enum）が変化したタイミングでトリガーされる。具体的には、レンダリングフレームの完了時にframeCompleted関数が呼び出され、健全性値が前回と異なる場合に通知が発行される。状態は「healthy」（正常）と「unhealthy」（異常）の2種類が存在する。

**通知の受信者**：当該ターミナルサーフェスを管理するアプリケーションランタイム（macOS/GTK等）が受信者となる。受信したランタイムは、ウィンドウタイトルバーへの警告アイコン表示、ステータスバーへのメッセージ表示、システム通知の発行など、プラットフォーム固有の方法でユーザーに情報を伝達する。

**通知内容の概要**：通知にはレンダラーの健全性状態（Health enum値）が含まれる。healthy/unhealthyの2値であり、詳細なエラー情報は含まれない。

**期待されるアクション**：unhealthy状態の通知を受けた場合、ユーザーはターミナルウィンドウの表示に問題がないか確認し、必要に応じてウィンドウのリサイズ、アプリケーションの再起動、グラフィックス設定の変更などの対処を行う。healthy状態への復帰時は、以前の警告表示をクリアする。

## 通知種別

アプリ内通知（UI表示変更） / システム警告（プラットフォーム依存）

## 送信仕様

### 基本情報

| 項目 | 内容 |
|-----|------|
| 送信方式 | 非同期（レンダースレッドからメールボックス経由） |
| 優先度 | 高（描画に影響するため） |
| リトライ | 無し（状態変化時のみ送信） |

### 送信先決定ロジック

通知は、健全性状態が変化したレンダラーに対応するサーフェスのメールボックスに送信される。サーフェスはアプリケーションランタイムのperformAction関数を通じて、renderer_healthアクションとして処理される。

## 通知テンプレート

### アプリ内通知の場合

| 項目 | 内容 |
|-----|------|
| 種別 | 状態変更通知 |
| 健全性状態 | healthy / unhealthy |
| 表示方法 | プラットフォーム依存 |

### 本文テンプレート

```
[unhealthy状態の場合]
レンダラーに問題が発生しました。表示に影響が出る可能性があります。

[healthy状態への復帰の場合]
（警告表示のクリア）
```

### 添付ファイル

| ファイル名 | 形式 | 条件 | 説明 |
|----------|------|------|------|
| なし | - | - | 添付ファイルはサポートしない |

## テンプレート変数

| 変数名 | 説明 | データ取得元 | 必須 |
|--------|------|-------------|-----|
| health | 健全性状態（healthy/unhealthy） | renderer.Health enum | Yes |

## 送信トリガー・条件

### トリガー一覧

| トリガー種別 | トリガーイベント | 送信条件 | 説明 |
|------------|----------------|---------|------|
| フレーム完了 | frameCompleted呼び出し | 健全性状態が前回と異なる場合 | レンダリングフレーム完了時のヘルスチェック |

### 送信抑止条件

| 条件 | 説明 |
|-----|------|
| 状態変化なし | 前回と同じ健全性状態の場合は通知を送信しない |
| メールボックスプッシュ失敗 | サーフェスメールボックスへの送信が失敗した場合は再試行なし |

## 処理フロー

### 送信フロー

```mermaid
flowchart TD
    A[レンダリングフレーム完了] --> B[frameCompleted呼び出し]
    B --> C{健全性状態取得}
    C --> D{前回と状態が異なる?}
    D -->|No| E[処理終了]
    D -->|Yes| F[Atomic変数更新]
    F --> G[メールボックスにプッシュ]
    G --> H[Surface.handleMessage]
    H --> I[updateRendererHealth]
    I --> J[performAction renderer_health]
    J --> K[アプリランタイム処理]
    K --> L[UI更新]
```

## データベース参照・更新仕様

### 参照テーブル一覧

| テーブル名 | 用途 | 備考 |
|-----------|------|------|
| なし | - | データベースは使用しない |

### 更新テーブル一覧

| テーブル名 | 操作 | 概要 |
|-----------|------|------|
| なし | - | データベースは使用しない |

## エラー処理

### エラーケース一覧

| エラー種別 | 発生条件 | 対処方法 |
|----------|---------|---------|
| メールボックスプッシュ失敗 | キュー満杯等 | 警告ログ出力のみ |
| performAction失敗 | アプリランタイムエラー | 警告ログ出力、処理続行 |

### リトライ仕様

| 項目 | 内容 |
|-----|------|
| リトライ回数 | 0回（状態変化時に再度トリガー） |
| リトライ間隔 | - |
| リトライ対象エラー | - |

## 配信設定

### レート制限

| 項目 | 内容 |
|-----|------|
| 1分あたり上限 | 制限なし（状態変化ベース） |
| 1日あたり上限 | 制限なし |

### 配信時間帯

制限なし（フレーム完了時に即座に処理）

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

- 健全性状態は内部情報であり、外部に漏洩してもセキュリティリスクは低い
- 不正なレンダラー状態による偽の警告表示は、信頼性の低下につながる可能性があるが、内部APIのためリスクは限定的

## 備考

- Health enumはc_int型として定義され、C言語ABIとの互換性を確保している
- レンダラーはMetal（macOS）とOpenGL（GTK/Linux）の2種類が存在し、両方で同じHealth enumを使用
- Atomic変数（std.atomic.Value）を使用して、レンダースレッドとメインスレッド間のスレッドセーフな状態共有を実現
- メールボックスへのプッシュは`.forever`オプションで永続的に試行される

---

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

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

### 推奨読解順序

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

レンダラー健全性の定義とアクションの構造を把握する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | renderer.zig | `src/renderer.zig` | Health enum定義（行44-54）を確認 |
| 1-2 | action.zig | `src/apprt/action.zig` | renderer_healthアクション定義（行222）を確認 |

**読解のコツ**: `Health = enum(c_int)`はC言語ABIとの互換性のため、c_int型として定義されている。

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

健全性状態の更新処理の入口を特定する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | generic.zig | `src/renderer/generic.zig` | frameCompleted関数（行1724-1742）を確認 |

**主要処理フロー**:
1. **行1726-1730**: 健全性値の比較（前回との差分チェック）
2. **行1731**: Atomic変数への状態保存
3. **行1733-1737**: メールボックスへのプッシュ
4. **行1741**: スワップチェインのフレームリリース

#### Step 3: メッセージ受信層を理解する

サーフェスがメッセージを受信し処理する流れを追跡する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | Surface.zig | `src/Surface.zig` | renderer_healthメッセージの処理（行1071, 1652-1658） |

**主要処理フロー**:
- **行1071**: handleMessage内でupdateRendererHealthを呼び出し
- **行1652**: 警告ログの出力
- **行1653-1658**: performActionでアプリランタイムに通知

#### Step 4: アプリランタイム層を理解する

各プラットフォームでの処理を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | SurfaceView.swift | `macos/Sources/Ghostty/Surface View/SurfaceView.swift` | macOSでの処理実装 |
| 4-2 | application.zig | `src/apprt/gtk/class/application.zig` | GTKでの処理実装 |

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

```
レンダリングフレーム完了
    |
    +-- frameCompleted() [renderer/generic.zig]
           |
           +-- health値比較 (load/store)
           |
           +-- surface_mailbox.push()
                  |
                  +-- Surface.handleMessage() [Surface.zig]
                         |
                         +-- updateRendererHealth()
                                |
                                +-- log.warn (ログ出力)
                                |
                                +-- rt_app.performAction()
                                       |
                                       +-- [macOS] SurfaceView処理
                                       |
                                       +-- [GTK] Application処理
```

### データフロー図

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

フレーム完了       --->  レンダラー             --->   Health enum値
イベント                 (generic.zig)
                              |
                              v
                         状態比較
                         (Atomic load/store)
                              |
                              v
                         メールボックス
                         (renderer_health)
                              |
                              v
                         Surface
                         (handleMessage)
                              |
                              v
                         アプリランタイム        --->   UI表示更新
                         (performAction)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| renderer.zig | `src/renderer.zig` | ソース | レンダラーモジュールとHealth enum定義 |
| generic.zig | `src/renderer/generic.zig` | ソース | 汎用レンダラー実装とframeCompleted |
| Metal.zig | `src/renderer/Metal.zig` | ソース | macOS Metal レンダラー |
| OpenGL.zig | `src/renderer/OpenGL.zig` | ソース | OpenGL レンダラー |
| Surface.zig | `src/Surface.zig` | ソース | サーフェス管理とメッセージ処理 |
| action.zig | `src/apprt/action.zig` | ソース | アプリケーションアクション定義 |
| SurfaceView.swift | `macos/Sources/Ghostty/Surface View/SurfaceView.swift` | ソース | macOS UI実装 |
| application.zig | `src/apprt/gtk/class/application.zig` | ソース | GTK アプリケーション実装 |
