# 通知設計書 75-キャッシュファイルロードデバッグ

## 概要

本ドキュメントは、プリコンパイル済みキャッシュファイルまたはオブジェクトキャッシュファイルのロード開始時に出力されるデバッグ通知の設計を定義する。

### 本通知の処理概要

パッケージのプリコンパイル済みキャッシュファイル（`.ji`）またはオブジェクトキャッシュファイル（`.so`/`.dylib`/`.dll`）のロードを開始する際に、デバッグレベルでロード対象を記録する通知機能である。

**業務上の目的・背景**：Juliaのプリコンパイルシステムでは、パッケージのロード時間短縮のためにシリアライズされたキャッシュファイルを使用する。通常のキャッシュファイル（`.ji`）とネイティブコードを含むオブジェクトキャッシュファイルの2種類が存在し、どちらからロードされるかの判別は、パフォーマンス診断や問題切り分けにおいて重要な情報である。本デバッグ通知により、実際にどのファイルからパッケージがロードされたかを追跡できる。

**通知の送信タイミング**：`_include_from_serialized()`関数内で、キャッシュファイルからのモジュール復元（C関数呼び出し）の直前に出力される。

**通知の受信者**：パッケージロードの問題を診断するJulia開発者、パッケージメンテナ。

**通知内容の概要**：ロード対象のキャッシュファイルパスとパッケージ名が通知される。

**期待されるアクション**：通常は情報提供のみ。ロードに問題がある場合のデバッグ情報として活用。

## 通知種別

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

## 送信仕様

### 基本情報

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

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

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

## 通知テンプレート

### メール通知の場合

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

### 本文テンプレート

```
Loading object cache file {ocachepath} for {pkg}
Loading cache file {path} for {pkg}
```

### 添付ファイル

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

## テンプレート変数

| 変数名 | 説明 | データ取得元 | 必須 |
|--------|------|-------------|-----|
| ocachepath | オブジェクトキャッシュファイルのパス | `_include_from_serialized()`の引数 | No（オブジェクトキャッシュの場合のみ） |
| path | キャッシュファイルのパス | `_include_from_serialized()`の引数 | Yes |
| pkg | パッケージのPkgId（`repr("text/plain", pkg)`で表示） | `_include_from_serialized()`の引数 | Yes |

## 送信トリガー・条件

### トリガー一覧

| トリガー種別 | トリガーイベント | 送信条件 | 説明 |
|------------|----------------|---------|------|
| キャッシュロード | オブジェクトキャッシュファイルのロード開始 | `ocachepath !== nothing` | loading.jl:1456 |
| キャッシュロード | 通常キャッシュファイルのロード開始 | `ocachepath === nothing` | loading.jl:1460 |

### 送信抑止条件

| 条件 | 説明 |
|-----|------|
| デバッグレベルが無効 | `@debug`はデフォルトで抑制されている |

## 処理フロー

### 送信フロー

```mermaid
flowchart TD
    A[_include_from_serialized呼び出し] --> B{ocachepath !== nothing?}
    B -->|Yes| C["@debug Loading object cache file"]
    B -->|No| D["@debug Loading cache file"]
    C --> E[jl_restore_package_image_from_file]
    D --> F[jl_restore_incremental]
    E --> G{復元結果}
    F --> G
    G -->|成功| H[モジュール登録]
    G -->|失敗| I[エラー返却]
```

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

### 参照テーブル一覧

| テーブル名 | 用途 | 備考 |
|-----------|------|------|
| 該当なし | - | ファイルシステムのみ参照 |

### 更新テーブル一覧

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

## エラー処理

### エラーケース一覧

| エラー種別 | 発生条件 | 対処方法 |
|----------|---------|---------|
| 復元失敗 | キャッシュファイルの復元が失敗した場合 | エラー情報を返却（デバッグログとは別のエラーパス） |

### リトライ仕様

| 項目 | 内容 |
|-----|------|
| リトライ回数 | なし |
| リトライ間隔 | - |
| リトライ対象エラー | - |

## 配信設定

### レート制限

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

### 配信時間帯

制限なし

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

- ファイルシステムのパス情報がデバッグログに含まれるが、デフォルトでは非表示

## 備考

- オブジェクトキャッシュファイルはネイティブコードを含む`.so`/`.dylib`/`.dll`形式のファイルで、`jl_restore_package_image_from_file`でロードされる
- 通常のキャッシュファイルは`.ji`形式で、`jl_restore_incremental`でロードされる
- ロード処理中は`require_lock`が一時的にアンロックされ、他のスレッドからのパッケージロードが可能になる

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | loading.jl | `base/loading.jl` | `PkgId`構造体とキャッシュファイルパスの管理 |

**読解のコツ**: `ocachepath`が`nothing`かどうかでオブジェクトキャッシュと通常キャッシュが区別される。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | loading.jl | `base/loading.jl` | `_include_from_serialized()`関数（1445-1474行目付近）：キャッシュロードの実行部 |

**主要処理フロー**:
1. **1445-1449行目**: 依存モジュールの準備（depmods配列の構築）
2. **1455-1456行目**: `ocachepath !== nothing`の場合、オブジェクトキャッシュのロードログ出力
3. **1457-1458行目**: `jl_restore_package_image_from_file` C関数呼び出し
4. **1459-1460行目**: `ocachepath === nothing`の場合、通常キャッシュのロードログ出力
5. **1461-1462行目**: `jl_restore_incremental` C関数呼び出し

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

```
require(pkg) (loading.jl)
    |
    +-- _tryrequire_from_serialized()
           |
           +-- _include_from_serialized(pkg, path, ocachepath, staledeps)
                  |
                  +-- @debug "Loading object cache file..." (loading.jl:1456)
                  |   +-- ccall(:jl_restore_package_image_from_file)
                  |
                  +-- @debug "Loading cache file..." (loading.jl:1460)
                      +-- ccall(:jl_restore_incremental)
```

### データフロー図

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

pkg (PkgId) ──────────────> _include_from_serialized()
path (キャッシュファイル) ──>      |
ocachepath (オブジェクト) ──>      +-- @debug ログ出力 ──────────> デバッグログ
depmods (依存情報) ──────>      |
                               +-- C関数でロード ─────────────> Module / Exception
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| loading.jl | `base/loading.jl` | ソース | `_include_from_serialized()`関数でのデバッグログ出力（1456, 1460行目） |
