# 通知設計書 12-一時ディレクトリ不在警告

## 概要

本ドキュメントは、Juliaの`tempdir()`関数において一時ディレクトリのパスが存在しないまたはディレクトリでない場合に発行される警告通知の設計仕様を記述する。

### 本通知の処理概要

本通知は、`tempdir()`関数がOSから取得した一時ディレクトリパスの妥当性を検証した際に、パスが存在しない、ディレクトリでない、またはアクセスに失敗した場合に警告を発行する処理である。3種類のバリエーションが存在する。

**業務上の目的・背景**：一時ディレクトリはファイルの一時保存、プリコンパイルキャッシュの格納、テストデータの配置など多くの処理で使用される基盤的なリソースである。一時ディレクトリが利用できない状態は、後続の多くの処理に影響を及ぼすため、早期に検出して開発者・ユーザーに通知する必要がある。環境変数（TMP、TEMP、TMPDIR等）の誤設定やディスク障害の早期発見に寄与する。

**通知の送信タイミング**：`tempdir()`関数が呼び出され、`uv_os_tmpdir`から取得したパスに対して`stat`を実行した結果、パスが存在しない（`!ispath(s)`）、ディレクトリでない（`!isdir(s)`）、またはアクセス時にIOError/SystemErrorが発生した場合に送信される。

**通知の受信者**：Juliaプロセスを実行しているユーザーおよび開発者。標準エラー出力を通じてログ表示される。

**通知内容の概要**：3つのバリエーションがある。(1)「tempdir path does not exist」+パス情報、(2)「tempdir path is not a directory」+パス情報、(3)「accessing tempdir path failed」+例外情報。いずれも取得された一時ディレクトリのパスを含む。

**期待されるアクション**：ユーザーは環境変数（TMP/TEMP/TMPDIR/USERPROFILE等）の設定を確認し、指定されたパスが有効なディレクトリとして存在することを確認する。必要に応じてディレクトリを作成するか、環境変数を正しいパスに修正する。

## 通知種別

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

## 送信仕様

### 基本情報

| 項目 | 内容 |
|-----|------|
| 送信方式 | 同期（`@warn`マクロによる即座のログ出力） |
| 優先度 | 中（一時ディレクトリの不在は多くの後続処理に影響） |
| リトライ | なし |

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

Juliaの標準ロギングフレームワーク（`CoreLogging`）を通じて、現在アクティブなロガーに送信される。デフォルトでは標準エラー出力（`stderr`）に出力される。

## 通知テンプレート

### メール通知の場合

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

### 本文テンプレート

```
# バリエーション1: パスが存在しない場合
Warning: tempdir path does not exist
  tempdir = "{一時ディレクトリパス}"

# バリエーション2: パスがディレクトリでない場合
Warning: tempdir path is not a directory
  tempdir = "{一時ディレクトリパス}"

# バリエーション3: アクセスに失敗した場合
Warning: accessing tempdir path failed
  exception = {例外オブジェクト}
```

### 添付ファイル

該当なし

## テンプレート変数

| 変数名 | 説明 | データ取得元 | 必須 |
|--------|------|-------------|-----|
| tempdir | 一時ディレクトリのパス文字列 | `uv_os_tmpdir` C関数の戻り値 | Yes（バリエーション1,2） |
| _exception | アクセス時に発生した例外オブジェクト | `stat(tempdir)`のcatch節 | Yes（バリエーション3） |

## 送信トリガー・条件

### トリガー一覧

| トリガー種別 | トリガーイベント | 送信条件 | 説明 |
|------------|----------------|---------|------|
| API呼出し | `tempdir()`関数の実行 | `!ispath(stat(tempdir))` | パスが存在しない |
| API呼出し | `tempdir()`関数の実行 | `ispath(s) && !isdir(s)` | パスが存在するがディレクトリでない |
| API呼出し | `tempdir()`関数の実行 | `stat(tempdir)`がIOError/SystemErrorを投げた場合 | パスへのアクセスそのものが失敗 |

### 送信抑止条件

| 条件 | 説明 |
|-----|------|
| パスが正常なディレクトリ | `stat`が成功し`ispath`かつ`isdir`の場合、警告は発行されない |

## 処理フロー

### 送信フロー

```mermaid
flowchart TD
    A[tempdir関数呼出し] --> B[uv_os_tmpdirでパス取得]
    B --> C{stat実行}
    C -->|成功| D{ispath確認}
    C -->|IOError/SystemError| E["@warn 'accessing tempdir path failed'"]
    D -->|存在しない| F["@warn 'tempdir path does not exist'"]
    D -->|存在する| G{isdir確認}
    G -->|ディレクトリでない| H["@warn 'tempdir path is not a directory'"]
    G -->|ディレクトリ| I[正常終了]
    E --> J[tempdirパスを返却]
    F --> J
    H --> J
    I --> J
```

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

### 参照テーブル一覧

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

### 更新テーブル一覧

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

## エラー処理

### エラーケース一覧

| エラー種別 | 発生条件 | 対処方法 |
|----------|---------|---------|
| IOError | `stat`がI/Oエラーを発生させた場合 | 警告ログを出力し、取得済みのtempdirパスをそのまま返却（処理は中断しない） |
| SystemError | `stat`がシステムエラーを発生させた場合 | 警告ログを出力し、取得済みのtempdirパスをそのまま返却（処理は中断しない） |
| その他の例外 | 上記以外の例外 | `rethrow()`により上位に伝播 |

### リトライ仕様

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

## 配信設定

### レート制限

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

### 配信時間帯

制限なし（`tempdir()`関数の呼出し時に随時発行）

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

通知にはシステムの一時ディレクトリパスが含まれる。このパスにはユーザー名が含まれる場合がある（例：Windowsの`C:\Users\{ユーザー名}\AppData\Local\Temp`）。ログが外部に転送される環境では、ユーザー情報の漏洩に注意が必要。

## 備考

- `tempdir()`はWindows/UNIX/macOSで参照する環境変数が異なる（Windows: TMP,TEMP,USERPROFILE / その他: TMPDIR,TMP,TEMP,TEMPDIR）
- 警告が出力された場合でも関数は一時ディレクトリパスを返却する（フェイルソフト設計）
- `uv_os_tmpdir`はlibuvのC関数であり、OS固有のAPI経由で一時ディレクトリを取得する

---

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

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

### 推奨読解順序

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

一時ディレクトリ取得に使用されるバッファとlibuvのC API呼出しの仕組みを理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | file.jl | `base/file.jl` | `tempdir()`関数全体（562-589行目）、`StringVector`バッファとCサイズ参照の使い方 |

**読解のコツ**: `ccall(:uv_os_tmpdir, ...)`はlibuvのC関数を直接呼び出す。`UV_ENOBUFS`はバッファサイズ不足を示し、ループでバッファを拡大して再試行する。

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

`tempdir()`関数のパス検証ロジックを理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | file.jl | `base/file.jl` | 577-587行目のtry-catch内のstat/ispath/isdir検証 |

**主要処理フロー**:
1. **562行目**: `function tempdir()` - 関数定義
2. **563-575行目**: `uv_os_tmpdir`を呼び出して一時ディレクトリパスを取得（バッファリサイズのループあり）
3. **576行目**: `tempdir = String(buf)` - パスを文字列に変換
4. **577行目**: `try` - パス検証開始
5. **578行目**: `s = stat(tempdir)` - パスの状態を取得
6. **579-580行目**: `!ispath(s)` - パスが存在しない場合に`@warn`
7. **581-582行目**: `!isdir(s)` - ディレクトリでない場合に`@warn`
8. **584-586行目**: IOError/SystemError発生時に`@warn`

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

```
tempdir()                           [base/file.jl:562]
    |
    +-- ccall(:uv_os_tmpdir)        [libuv C API]
    |
    +-- stat(tempdir)               [base/stat.jl]
    |       |
    |       +-- ispath(s)
    |       +-- isdir(s)
    |
    +-- @warn (条件付き, 3パターン) [CoreLogging]
```

### データフロー図

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

環境変数              --> uv_os_tmpdir            --> パス文字列(buf)
(TMP/TEMP/TMPDIR等)       [base/file.jl:566]

パス文字列            --> stat(tempdir)           --> Stat構造体
                          [base/file.jl:578]

Stat構造体            --> ispath/isdir判定         --> 警告(3種) or 正常
                          [base/file.jl:579-586]

パス文字列            -->                         --> return tempdir
                          [base/file.jl:588]
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| file.jl | `base/file.jl` | ソース | `tempdir()`関数の定義と警告ロジック |
| stat.jl | `base/stat.jl` | ソース | `stat`関数、`ispath`、`isdir`の定義 |
| logging.jl | `base/logging.jl` | ソース | `@warn`マクロの定義 |
