# 通知設計書 76-拡張機能ロードデバッグ

## 概要

本ドキュメントは、Juliaの拡張機能（Extension）のロード完了時に出力されるデバッグ通知の設計を定義する。

### 本通知の処理概要

パッケージの拡張機能（Package Extensions）が正常にロードされた際に、ロード完了をデバッグレベルで記録する通知機能である。

**業務上の目的・背景**：Julia 1.9で導入されたパッケージ拡張機能（Package Extensions）は、特定のパッケージがロードされた時にのみ有効化される条件付き機能を提供する。例えば、パッケージAがパッケージBの拡張機能を持つ場合、Bがロードされたタイミングでその拡張機能が自動的にロードされる。本デバッグ通知により、拡張機能のロード完了を追跡でき、拡張機能が期待通りにロードされているかの診断に役立つ。

**通知の送信タイミング**：`run_extension_callbacks()`関数内で、`_require_prelocked()`による拡張機能のロードが成功した直後に出力される。

**通知の受信者**：拡張機能のロード状況を診断するJulia開発者、パッケージメンテナ。

**通知内容の概要**：ロードされた拡張機能の名前と、その親パッケージの名前が通知される。

**期待されるアクション**：通常は情報提供のみ。拡張機能が期待通りにロードされない場合のデバッグ情報として活用。

## 通知種別

ログ出力（`@debug`レベル）

## 送信仕様

### 基本情報

| 項目 | 内容 |
|-----|------|
| 送信方式 | 同期（拡張機能ロード完了時に即座に出力） |
| 優先度 | 低（デバッグレベル、通常は表示されない） |
| リトライ | なし |

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

`@debug`マクロを通じてJuliaの標準ログシステムに出力される。デフォルトでは表示されない。

## 通知テンプレート

### メール通知の場合

該当なし（ログ出力のみ）

### 本文テンプレート

```
Extension {extid.id.name} of {extid.parentid.name} loaded
```

### 添付ファイル

| ファイル名 | 形式 | 条件 | 説明 |
|----------|------|------|------|
| 該当なし | - | - | - |

## テンプレート変数

| 変数名 | 説明 | データ取得元 | 必須 |
|--------|------|-------------|-----|
| extid.id.name | 拡張機能のパッケージ名 | `ExtensionId`構造体の`id`フィールド | Yes |
| extid.parentid.name | 親パッケージの名前 | `ExtensionId`構造体の`parentid`フィールド | Yes |

## 送信トリガー・条件

### トリガー一覧

| トリガー種別 | トリガーイベント | 送信条件 | 説明 |
|------------|----------------|---------|------|
| 拡張機能ロード | `_require_prelocked(extid.id)`成功 | ロードが例外なく完了 | loading.jl:1765 |

### 送信抑止条件

| 条件 | 説明 |
|-----|------|
| デバッグレベルが無効 | `@debug`はデフォルトで抑制されている |
| 拡張機能のロード失敗 | ロード中に例外が発生した場合、デバッグログではなく`@error`が出力される |

## 処理フロー

### 送信フロー

```mermaid
flowchart TD
    A[トリガーパッケージロード] --> B[run_extension_callbacks呼び出し]
    B --> C[loading_extension = true]
    C --> D[_require_prelocked実行]
    D --> E{ロード成功?}
    E -->|Yes| F["@debug Extension loaded"]
    E -->|No| G["@error Error during loading of extension"]
    F --> H[loading_extension = false]
    G --> H
    H --> I[終了]
```

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

### 参照テーブル一覧

| テーブル名 | 用途 | 備考 |
|-----------|------|------|
| 該当なし | - | メモリ上のデータのみ参照 |

### 更新テーブル一覧

| テーブル名 | 操作 | 概要 |
|-----------|------|------|
| 該当なし | - | ログ出力のみ |

## エラー処理

### エラーケース一覧

| エラー種別 | 発生条件 | 対処方法 |
|----------|---------|---------|
| 拡張機能ロード失敗 | `_require_prelocked`が例外を送出 | `@error`ログ出力。インクリメンタルプリコンパイル中はrethrow、それ以外は`Base.retry_load_extensions()`の使用を案内 |

### リトライ仕様

| 項目 | 内容 |
|-----|------|
| リトライ回数 | なし（デバッグログ自体にリトライなし） |
| リトライ間隔 | - |
| リトライ対象エラー | - |

## 配信設定

### レート制限

| 項目 | 内容 |
|-----|------|
| 1分あたり上限 | 制限なし |
| 1日あたり上限 | 制限なし |

### 配信時間帯

制限なし

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

- パッケージ名がログに含まれるが、機密情報ではない

## 備考

- 拡張機能ロード中は`loading_extension`グローバル変数が`true`に設定され、Distributedパッケージがコールバック内で拡張機能をロードできるようにする
- インクリメンタルプリコンパイル中（`JLOptions().incremental != 0`）は、拡張機能のロード失敗が即座にrethrowされる（fail-fast）
- 拡張機能のロードに失敗した場合は`Base.retry_load_extensions()`で再試行可能

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | loading.jl | `base/loading.jl` | `ExtensionId`構造体：拡張機能の識別子（`id`と`parentid`フィールド） |

**読解のコツ**: `ExtensionId`の`id`は拡張機能自体のPkgId、`parentid`は拡張機能を定義している親パッケージのPkgIdである。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | loading.jl | `base/loading.jl` | `run_extension_callbacks()`関数（1759-1779行目）：拡張機能のロード実行 |

**主要処理フロー**:
1. **1763行目**: `loading_extension = true`に設定
2. **1764行目**: `_require_prelocked(extid.id)`で拡張機能をロード
3. **1765行目**: `@debug "Extension $(extid.id.name) of $(extid.parentid.name) loaded"`
4. **1779行目**: `loading_extension = false`に復帰

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

```
パッケージロード完了
    |
    +-- run_extension_callbacks(extid::ExtensionId) (loading.jl:1759)
           |
           +-- loading_extension = true (loading.jl:1763)
           +-- _require_prelocked(extid.id) (loading.jl:1764)
           |      +-- 拡張機能のロード処理
           |
           +-- @debug "Extension ... loaded" (loading.jl:1765)
           +-- loading_extension = false (loading.jl:1779)
```

### データフロー図

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

ExtensionId ──────────────> run_extension_callbacks()
  - id (拡張PkgId)              |
  - parentid (親PkgId)         +-- _require_prelocked() ──> Module
                               |
                               +-- @debug ──────────────────> デバッグログ
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| loading.jl | `base/loading.jl` | ソース | `run_extension_callbacks()`関数でのデバッグログ出力（1765行目）、`ExtensionId`構造体、`_require_prelocked()`関数 |
