# 通知設計書 9-UDPソケット通知

## 概要

本ドキュメントは、Node.jsのdgramモジュールにおける診断チャンネル通知機能の設計書である。

### 本通知の処理概要

UDPソケット通知は、Node.jsアプリケーションがUDP（User Datagram Protocol）ソケットを作成する際に診断チャンネルに通知を送信する機能を提供する。これにより、UDPソケットの作成を外部から監視・計装することが可能となる。

**業務上の目的・背景**：リアルタイム通信、DNS問い合わせ、ゲームサーバー、IoTデバイス通信などでUDPは広く使用される。UDPソケット通知により、ソケットの作成タイミングを監視し、アプリケーションのネットワーク利用状況を把握できる。UDP通信は軽量だが監視が難しいため、この通知機能は有用である。

**通知の送信タイミング**：
- udp.socket: dgram.createSocket()またはnew dgram.Socket()によるUDPソケット作成時

**通知の受信者**：診断チャンネルに対してsubscribe()で登録したコールバック関数。APMツール、トレーシングライブラリ、カスタム監視コードなどが想定される。

**通知内容の概要**：作成されたUDPソケットオブジェクト。

**期待されるアクション**：購読者は受信したデータを使用して、ソケットのトラッキング、メトリクス収集、ログ出力などを行う。

## 通知種別

内部イベント通知（diagnostics_channel）

## 送信仕様

### 基本情報

| 項目 | 内容 |
|-----|------|
| 送信方式 | 同期 |
| 優先度 | 中（ソケット作成は頻繁ではない） |
| リトライ | なし（同期実行のため） |

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

チャンネルに対してsubscribe()を呼び出した購読者に送信される。hasSubscribersで事前チェックを行い、購読者がいない場合はpublish()をスキップしてパフォーマンスオーバーヘッドを最小化。

## 通知テンプレート

### チャンネル一覧

| チャンネル名 | タイミング | 説明 |
|-------------|---------|------|
| udp.socket | ソケット作成時 | Socketコンストラクタ完了時に発火 |

### データ構造

```javascript
// udp.socket
{
  socket: dgram.Socket  // UDPソケットオブジェクト
}
```

### 添付ファイル

該当なし（プログラム内部通知のため）

## テンプレート変数

| 変数名 | 説明 | データ取得元 | 必須 |
|--------|------|-------------|-----|
| socket | UDPソケットオブジェクト | dgram.Socketインスタンス | Yes |

## 送信トリガー・条件

### トリガー一覧

| トリガー種別 | トリガーイベント | 送信条件 | 説明 |
|------------|----------------|---------|------|
| ソケット作成 | new Socket() | hasSubscribers == true | コンストラクタ完了時 |

### 送信抑止条件

| 条件 | 説明 |
|-----|------|
| 購読者なし | hasSubscribersがfalseの場合、publish()をスキップ |

## 処理フロー

### 送信フロー

```mermaid
flowchart TD
    A[dgram.createSocket呼び出し] --> B[new Socket]
    B --> C[ソケット初期化処理]
    C --> D[ハンドル作成]
    D --> E[状態初期化]
    E --> F{hasSubscribers?}
    F -->|Yes| G[udp.socket発火]
    F -->|No| H[スキップ]
    G --> I[ソケット返却]
    H --> I
```

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

### 参照テーブル一覧

本通知はデータベースを使用しない。

| テーブル名 | 用途 | 備考 |
|-----------|------|------|
| なし | - | メモリ内オブジェクトのみ使用 |

### 更新テーブル一覧

| テーブル名 | 操作 | 概要 |
|-----------|------|------|
| なし | - | データベース更新なし |

## エラー処理

### エラーケース一覧

| エラー種別 | 発生条件 | 対処方法 |
|----------|---------|---------|
| 無効なタイプ | type !== 'udp4' && type !== 'udp6' | ERR_SOCKET_BAD_TYPE例外（通知前にエラー） |
| 無効なオプション | 不正なオプション値 | バリデーションエラー（通知前にエラー） |

### リトライ仕様

| 項目 | 内容 |
|-----|------|
| リトライ回数 | なし（通知自体にはリトライなし） |
| リトライ間隔 | なし |
| リトライ対象エラー | なし |

## 配信設定

### レート制限

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

### 配信時間帯

制限なし（プログラム実行中は常時利用可能）

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

- ソケットオブジェクトからローカルアドレス情報にアクセスできるため、ログ出力時には注意が必要
- BlockListオプションが設定されている場合、その設定内容にアクセスできる
- 購読者のパフォーマンスがソケット作成のパフォーマンスに影響するため、軽量な処理を心がける

## 備考

- Node.js v18.11.0でudp.socketが追加
- hasSubscribersチェックにより、購読者がいない場合のオーバーヘッドは最小限
- dgram.createSocket()は内部でnew Socket()を呼び出すため、どちらの方法でも通知は発火する
- ソケット作成時のみ通知が発火し、bind()やsend()などの操作では通知は発火しない
- receiveBlockListやsendBlockListなどのオプションはソケットオブジェクトの状態から参照可能

---

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

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

### 推奨読解順序

#### Step 1: チャンネル定義を理解する

まず、診断チャンネルの定義箇所を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | dgram.js | `lib/dgram.js` | 84-85行目：udpSocketChannelの定義 |

**読解のコツ**: dc.channel()で通常チャンネルを作成している点を確認する。

#### Step 2: ソケットコンストラクタを理解する

Socketコンストラクタ内での通知を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | dgram.js | `lib/dgram.js` | 108-179行目：Socketコンストラクタ全体 |
| 2-2 | dgram.js | `lib/dgram.js` | 180-184行目：udp.socket通知 |

**主要処理フロー**:
1. **108行目**: Socket関数の開始
2. **117-141行目**: オプションの解析と検証
3. **143行目**: ハンドル作成（newHandle）
4. **152-165行目**: 状態オブジェクト初期化
5. **167-179行目**: シグナル処理
6. **180-184行目**: hasSubscribersチェックとpublish()

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

```
dgram.createSocket()
    │
    └─ new Socket() [108行目]
           │
           ├─ EventEmitter.call() [109行目]
           │
           ├─ オプション解析 [117-141行目]
           │
           ├─ newHandle() [143行目]
           │      └─ UDPハンドル作成
           │
           ├─ 状態初期化 [152-165行目]
           │      └─ kStateSymbol設定
           │
           ├─ シグナル処理 [167-179行目]
           │      └─ AbortSignal対応
           │
           └─ udpSocketChannel.publish() [180-184行目]
                  └─ { socket: this }
```

### データフロー図

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

createSocket()          Socket                     診断チャンネル購読者
    │                        │                            │
    ▼                        ▼                            ▼
options ──────────▶ new Socket() ─────────────▶ udp.socket
    │                        │                            │
    │                        ▼                            ▼
    │              初期化処理                      { socket }
    │                        │
    │                        ▼
    └─────────────▶ Socketインスタンス
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| dgram.js | `lib/dgram.js` | ソース | dgramモジュール実装、診断チャンネル通知 |
| diagnostics_channel.js | `lib/diagnostics_channel.js` | ソース | diagnostics_channelモジュール |
| udp_wrap.cc | `src/udp_wrap.cc` | ネイティブ | UDPバインディング |
