# 通知設計書 13-一時ファイルクリーンアップ失敗警告

## 概要

本ドキュメントは、Juliaの一時パスのクリーンアップ処理において、一時ファイルやディレクトリの削除に失敗した場合に発行される警告通知（`@warn "Failed to clean up temporary path"`）の設計仕様を記述する。

### 本通知の処理概要

本通知は、Juliaプロセスの終了時に実行される一時ファイルクリーンアップ処理において、`rm`による一時パスの削除に失敗した場合に警告を発行する処理である。クリーンアップ処理は子プロセスとして分離実行される。

**業務上の目的・背景**：Juliaは`mktemp`や`mktempdir`で作成された一時ファイル/ディレクトリをプロセス終了時に自動的にクリーンアップする。この自動クリーンアップが失敗した場合、ディスク上に不要な一時ファイルが残留し、ディスク容量の逼迫やセキュリティリスクにつながる可能性がある。本警告は、クリーンアップの失敗をユーザーに通知し、手動対応の必要性を示すために存在する。

**通知の送信タイミング**：Juliaプロセスの終了時（`atexit`コールバック）に実行されるクリーンアップ処理において、`rm(path, force=true, recursive=true)`が例外を発生させた場合に送信される。この処理は、メインプロセスから分離された子プロセス内で実行される。

**通知の受信者**：子プロセスの標準エラー出力（`stderr`）を通じて表示される。メインのJuliaプロセスではなく、デタッチされた子プロセス内で出力されるため、メインプロセスの終了後に表示される可能性がある。

**通知内容の概要**：「Failed to clean up temporary path {パス}」というメッセージとともに、削除に失敗した一時パスの情報と例外内容が出力される。`_group=:file`が指定されておりファイル操作カテゴリとして分類される。

**期待されるアクション**：ユーザーは、報告された一時パスを手動で確認・削除する。また、ファイルがロックされている場合はロックの原因を調査する。

## 通知種別

ログ（Warn） - Juliaの標準ログシステム（`@warn`マクロ）を通じたコンソール警告出力

## 送信仕様

### 基本情報

| 項目 | 内容 |
|-----|------|
| 送信方式 | 非同期（デタッチされた子プロセス内で実行） |
| 優先度 | 低（プロセス終了時のクリーンアップ失敗） |
| リトライ | なし（個々のパス削除について） |

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

子プロセスの標準エラー出力（`stderr`）に出力される。メインプロセスの`stderr`はデタッチ時に引き継がれる。

## 通知テンプレート

### メール通知の場合

該当なし（コンソールログ出力のみ）

### 本文テンプレート

```
Warning: Failed to clean up temporary path "{一時パス}"
{例外メッセージ}
```

### 添付ファイル

該当なし

## テンプレート変数

| 変数名 | 説明 | データ取得元 | 必須 |
|--------|------|-------------|-----|
| path | 削除に失敗した一時パス | `TEMP_CLEANUP`リストの各エントリ | Yes |
| ex | 発生した例外のメッセージ | `rm`呼出しのcatch節 | Yes |
| _group | ログのグループ分類 | 定数`:file` | Yes |

## 送信トリガー・条件

### トリガー一覧

| トリガー種別 | トリガーイベント | 送信条件 | 説明 |
|------------|----------------|---------|------|
| プロセス終了 | `atexit`コールバックからの`temp_cleanup_postprocess`実行 | `rm(path, force=true, recursive=true)`が例外を発生 | 各一時パスの削除試行が失敗した場合 |

### 送信抑止条件

| 条件 | 説明 |
|-----|------|
| パスが正常に削除された | `rm`が成功した場合、警告は発行されない |
| TEMP_CLEANUPリストが空 | クリーンアップ対象が存在しない場合 |

## 処理フロー

### 送信フロー

```mermaid
flowchart TD
    A[プロセス終了 atexit] --> B[temp_cleanup_atexit]
    B --> C[temp_cleanup_purge_all]
    C --> D[temp_cleanup_postprocess]
    D --> E{TEMP_CLEANUPリストが空?}
    E -->|空| F[終了]
    E -->|非空| G[子プロセス起動 - デタッチ]
    G --> H[sleep 1秒]
    H --> I[cleanuplistの各pathについてループ]
    I --> J[rm path force=true recursive=true]
    J -->|成功| K[次のpathへ]
    J -->|失敗| L["@warn 'Failed to clean up temporary path'"]
    L --> K
    K -->|残りあり| I
    K -->|完了| F
```

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

### 参照テーブル一覧

該当なし（データベースを使用しない）

### 更新テーブル一覧

該当なし（データベースを使用しない）

## エラー処理

### エラーケース一覧

| エラー種別 | 発生条件 | 対処方法 |
|----------|---------|---------|
| ファイルロック | 他プロセスがファイルを使用中 | 警告ログを出力し、次のパスの処理を続行 |
| アクセス権限 | 削除権限がない | 警告ログを出力し、次のパスの処理を続行 |
| パス不在 | パスが既に削除されている | `force=true`により無視される |

### リトライ仕様

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

## 配信設定

### レート制限

| 項目 | 内容 |
|-----|------|
| 1分あたり上限 | なし（クリーンアップリスト内の各パスについて発行） |
| 1日あたり上限 | なし |

### 配信時間帯

制限なし（プロセス終了時に実行）

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

一時ファイルのパスにはプロセスID、ユーザー名、実行中のパッケージ情報が含まれる可能性がある。クリーンアップが失敗した一時ファイルは、機密情報（SecretBufferの内容など）を含む可能性があるため、手動削除が推奨される。

## 備考

- クリーンアップ処理は子プロセスとしてデタッチされて実行される（`detach=true`）
- 子プロセスは`sleep(1)`の後にクリーンアップを開始する（OS側の準備待ち）
- `TEMP_CLEANUP`は`TEMP_CLEANUP_LOCK`で保護されたグローバルなクリーンアップリスト
- `prepare_for_deletion`関数がクリーンアップ前にディレクトリの書き込み権限を確保する
- `rmcmd`は文字列としてJuliaコードを組み立て、子プロセスの`-e`オプションとして実行される

---

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

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

### 推奨読解順序

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

一時ファイルクリーンアップの管理構造を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | file.jl | `base/file.jl` | `TEMP_CLEANUP`辞書と`TEMP_CLEANUP_LOCK`ロックの定義（670行目付近の`@lock TEMP_CLEANUP_LOCK`パターン） |

**読解のコツ**: `TEMP_CLEANUP`は`Dict{String,Bool}`型で、キーが一時パス、値がASAP（即時削除）フラグ。`@lock`マクロでスレッドセーフなアクセスを保証。

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

プロセス終了時のクリーンアップチェーンを理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | file.jl | `base/file.jl` | `__postinit__`（718-720行目）で`atexit(temp_cleanup_atexit)`を登録 |
| 2-2 | file.jl | `base/file.jl` | `temp_cleanup_atexit`（713-716行目）から`temp_cleanup_purge_all`と`temp_cleanup_postprocess`の呼出し |

**主要処理フロー**:
1. **718行目**: `__postinit__`でatexitフックを登録
2. **713行目**: `temp_cleanup_atexit`がプロセス終了時に呼出される
3. **714行目**: `temp_cleanup_purge_all()`で可能な限り削除を試行
4. **715行目**: `temp_cleanup_postprocess`で残りのパスを子プロセスに委譲

#### Step 3: 子プロセスでのクリーンアップ処理を理解する

デタッチされた子プロセスで実行される`rmcmd`の内容を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | file.jl | `base/file.jl` | `temp_cleanup_postprocess`（691-711行目）での子プロセス生成と`rmcmd`文字列 |

**主要処理フロー**:
- **693-702行目**: `rmcmd`文字列内の処理ロジック（stdinから読み取り、sleep後にrmループ）
- **700行目**: `@warn "Failed to clean up temporary path ..."` - 本通知の発行箇所
- **704行目**: `Cmd`でJulia子プロセスを構築（`--startup-file=no`, `-e`, detach=true）
- **706行目**: `run(cmd, pw, devnull, stderr; wait=false)` - 子プロセスをバックグラウンド実行

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

```
__postinit__()                          [base/file.jl:718]
    |
    +-- atexit(temp_cleanup_atexit)      [登録]

temp_cleanup_atexit()                   [base/file.jl:713]
    |
    +-- temp_cleanup_purge_all()         [base/file.jl:659]
    |       |
    |       +-- @lock TEMP_CLEANUP_LOCK
    |       +-- GC.gc(true)
    |       +-- temp_cleanup_purge_prelocked(true)
    |
    +-- temp_cleanup_postprocess(keys)   [base/file.jl:691]
            |
            +-- julia --startup-file=no -e rmcmd  [子プロセス]
                    |
                    +-- sleep(1)
                    +-- rm(path, force=true, recursive=true)
                    +-- @warn (失敗時)
```

### データフロー図

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

TEMP_CLEANUP辞書   -->  temp_cleanup_atexit       -->  削除試行
                         [base/file.jl:713]

残りのパスリスト   -->  子プロセスのstdinへ書込    -->  子プロセス
                         [base/file.jl:707]

各パス             -->  rm(path)                  -->  削除結果
                         [子プロセス内]                  |成功 or @warn
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| file.jl | `base/file.jl` | ソース | 一時ファイル管理とクリーンアップ処理全体 |
| logging.jl | `base/logging.jl` | ソース | `@warn`マクロの定義 |
| cmd.jl | `base/cmd.jl` | ソース | `Cmd`型と子プロセス生成 |
