# 通知設計書 12-+irc-disconnect-hook通知

## 概要

本ドキュメントは、Doom EmacsのIRCモジュールにおける+irc-disconnect-hook通知機能の設計仕様を記述する。この機能は、IRC接続が切断された際にカスタムフックを実行し、ユーザーに接続切断を通知するとともに、再接続や後処理のためのカスタマイズポイントを提供する。

### 本通知の処理概要

+irc-disconnect-hookは、circeがIRC接続の切断を検知した際に実行されるフック関数群である。このフックにより、ユーザーは接続切断時のカスタム処理（通知表示、再接続試行、ログ記録など）を実装できる。

**業務上の目的・背景**：IRC接続はネットワーク障害、サーバーダウン、タイムアウトなど様々な理由で切断される可能性がある。接続切断を即座に検知し、適切な対応を取ることは、リアルタイムコミュニケーションの継続性を維持するために重要である。本フックは、切断イベントに対するカスタム処理を可能にし、再接続シナリオやエラー通知の実装を容易にする。

**通知の送信タイミング**：circeがIRCサーバーとの接続切断を検知した直後、`circe--irc-conn-disconnected`関数の実行後に`+irc-disconnect-hook`が実行される。これはネットワークエラー、サーバー側の切断、または明示的な切断コマンドの実行時に発生する。

**通知の受信者**：このフックに登録された関数が実行されるため、受信者はEmacs内で実行されるカスタム処理となる。ユーザー向けの視覚的通知が必要な場合は、フック関数内で`message`関数やデスクトップ通知を実装する必要がある。

**通知内容の概要**：フック自体は引数を取らないが、フック関数内でcirceのバッファ情報や接続状態を参照することで、どのサーバーとの接続が切断されたかを特定できる。

**期待されるアクション**：ユーザーまたはシステムは、接続切断を認識し、必要に応じて再接続を試みる、ログを確認する、または手動で再接続コマンドを実行することが期待される。

## 通知種別

フック実行（Emacs内部イベント）
- ユーザーへの視覚的通知は、フック関数の実装に依存

## 送信仕様

### 基本情報

| 項目 | 内容 |
|-----|------|
| 送信方式 | 同期（フック実行） |
| 優先度 | 高 |
| リトライ | なし（フック自体） |

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

フックに登録されたすべての関数が順次実行される。`run-hooks`によりEmacs標準のフック実行メカニズムに従う。

## 通知テンプレート

### フック実行の場合

| 項目 | 内容 |
|-----|------|
| フック名 | +irc-disconnect-hook |
| 引数 | なし |
| 実行タイミング | circe--irc-conn-disconnected の :after |

### 本文テンプレート

フック関数内で独自にメッセージを生成する場合の例：
```elisp
(add-hook '+irc-disconnect-hook
          (lambda ()
            (message "IRC connection disconnected")))
```

### 添付ファイル

| ファイル名 | 形式 | 条件 | 説明 |
|----------|------|------|------|
| N/A | - | - | フック実行のため添付なし |

## テンプレート変数

| 変数名 | 説明 | データ取得元 | 必須 |
|--------|------|-------------|-----|
| N/A | フック自体は引数を取らない | - | - |

## 送信トリガー・条件

### トリガー一覧

| トリガー種別 | トリガーイベント | 送信条件 | 説明 |
|------------|----------------|---------|------|
| イベント | circe--irc-conn-disconnected | 常時 | IRC接続切断検知時に必ず実行 |

### 送信抑止条件

| 条件 | 説明 |
|-----|------|
| フックが空 | +irc-disconnect-hookに関数が登録されていない場合は何も実行されない |

## 処理フロー

### 送信フロー

```mermaid
flowchart TD
    A[IRC接続切断検知] --> B[circe--irc-conn-disconnected実行]
    B --> C[defadvice! :after実行]
    C --> D[run-hooks '+irc-disconnect-hook]
    D --> E{フック関数あり?}
    E -->|Yes| F[登録された関数を順次実行]
    E -->|No| G[終了]
    F --> H{全関数実行完了?}
    H -->|Yes| G
    H -->|No| F
```

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

### 参照テーブル一覧

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

### テーブル別参照項目詳細

本機能はデータベースを使用しない。

### 更新テーブル一覧

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

## エラー処理

### エラーケース一覧

| エラー種別 | 発生条件 | 対処方法 |
|----------|---------|---------|
| フック関数エラー | 登録された関数がエラーを発生 | 標準的なElispエラーハンドリングに従う |

### リトライ仕様

| 項目 | 内容 |
|-----|------|
| リトライ回数 | 0（リトライなし） |
| リトライ間隔 | N/A |
| リトライ対象エラー | なし |

## 配信設定

### レート制限

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

### 配信時間帯

制限なし（接続切断イベント発生時に常に実行）

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

- フック関数は任意のElispコードを実行できるため、信頼できるコードのみを登録すること
- 再接続処理を実装する場合、認証情報の取り扱いに注意すること
- ログ記録を行う場合、機密情報（パスワード、トークン）を含めないこと

## 備考

- このフックは即時再接続が失敗するシナリオ（例：ネットワーク全断）での代替処理に有用
- circe-reconnectと組み合わせて、段階的な再接続戦略を実装できる
- フックのドキュメントに「Useful for scenarios where an instant reconnect will not be successful」と記載されている

---

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

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

### 推奨読解順序

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

フック変数の定義を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | config.el | `modules/app/irc/config.el` | +irc-disconnect-hook変数の定義（行15-17） |

**読解のコツ**: defvarで定義されるフック変数は、nilで初期化され、add-hookで関数を追加する。

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

フックの実行トリガーとなるadvice定義を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | config.el | `modules/app/irc/config.el` | defadvice!によるフック実行（行89-92） |

**主要処理フロー**:
1. **行89**: defadvice!マクロでadviceを定義
2. **行90**: ドキュメント文字列「Runs `+irc-disconnect-hook' after circe disconnects.」
3. **行91**: `:after #'circe--irc-conn-disconnected`で切断後に実行を指定
4. **行92**: `(run-hooks '+irc-disconnect-hook)`でフックを実行

#### Step 3: 関連する終了処理を理解する

IRC終了時の処理フローを理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | irc.el | `modules/app/irc/autoload/irc.el` | +irc/quit関数（行49-63） |

**主要処理フロー**:
- **行52**: `(y-or-n-p "Really kill IRC session?")`で確認
- **行56-57**: +irc--defer-timerのキャンセル
- **行58-59**: disable-circe-notificationsの呼び出し
- **行60**: circe-modeバッファの一括削除

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

```
circe--irc-conn-disconnected（circe内部）
    │
    └─ [defadvice! :after]
           │
           └─ run-hooks '+irc-disconnect-hook
                  │
                  ├─ ユーザー定義フック関数1
                  ├─ ユーザー定義フック関数2
                  └─ ...
```

### データフロー図

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

IRC切断イベント ───▶ circe ───▶ circe--irc-conn-disconnected
                                     │
                                     └─ defadvice! :after
                                            │
                                            └─ run-hooks '+irc-disconnect-hook
                                                   │
                                                   └─ ユーザー定義処理
                                                          │
                                                          ├─ メッセージ表示
                                                          ├─ 再接続試行
                                                          └─ ログ記録
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| config.el | `modules/app/irc/config.el` | ソース | +irc-disconnect-hookの定義とadvice設定 |
| irc.el | `modules/app/irc/autoload/irc.el` | ソース | IRC関連の自動ロード関数（+irc/quit等） |
