# 通知設計書 22-ブロードキャストイベント

## 概要

本ドキュメントは、Ruby on Rails フレームワークにおける `broadcast.action_cable` 計装イベント（Instrumentation Event）の仕様を定義する。このイベントは ActionCable がブロードキャストを実行する際に発行される内部計装通知であり、WebSocket通信のパフォーマンス監視やデバッグに活用される。

### 本通知の処理概要

`broadcast.action_cable` イベントは、ActionCable サーバーがブロードキャストチャンネルにメッセージを配信する際に発行される計装イベントである。

**業務上の目的・背景**：リアルタイムWebアプリケーションにおいて、ActionCable によるブロードキャストは重要な通信機構である。このイベントを購読することで、どのブロードキャストチャンネルにどのようなメッセージが配信されたか、配信にどれだけの時間がかかったかを計測・記録できる。これにより、WebSocket通信のパフォーマンス監視、メッセージ配信のトラブルシューティング、およびAPMツール（Application Performance Monitoring）との連携が可能となる。

**通知の送信タイミング**：`ActionCable::Server::Broadcasting::Broadcaster#broadcast` メソッドが呼び出され、メッセージがPub/Subシステムを通じて配信される際に発行される。具体的には、`Broadcaster` クラスの `broadcast` メソッド内で `ActiveSupport::Notifications.instrument` を通じてイベントが発行され、ブロック内でメッセージのエンコードとPubSubへの配信が行われる。

**通知の受信者**：このイベントは `ActiveSupport::Notifications.subscribe` を使用して購読するサブスクライバーに配信される。デフォルトでは特定のログサブスクライバーは登録されていないが、アプリケーション開発者やAPMツールが独自のサブスクライバーを登録することで監視が可能となる。

**通知内容の概要**：イベントのペイロードには、ブロードキャスト先のチャンネル名（`:broadcasting`）、配信するメッセージ（`:message`）、およびメッセージのエンコーダー（`:coder`）が含まれる。イベント自体には開始時刻、終了時刻、処理時間（duration）、ユニークIDなどのメタデータも含まれる。

**期待されるアクション**：受信者（サブスクライバー）は、このイベントを使用してブロードキャスト配信のログ記録、メトリクス収集、パフォーマンス監視ダッシュボードへのデータ送信、またはカスタムビジネスロジックの実行を行うことが期待される。

## 通知種別

計装通知（ActiveSupport::Notifications Instrumentation Event）

## 送信仕様

### 基本情報

| 項目 | 内容 |
|-----|------|
| 送信方式 | 同期（ブロック実行中にイベント発行） |
| 優先度 | 中（計装イベントとして標準的な優先度） |
| リトライ | なし（計装イベントは一度のみ発行） |

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

`ActiveSupport::Notifications` に登録されているすべてのサブスクライバーに対してブロードキャストされる。サブスクライバーは以下の方法で登録可能：

1. `ActiveSupport::Notifications.subscribe("broadcast.action_cable")` - 特定イベントの購読
2. `ActiveSupport::Notifications.subscribe(/action_cable/)` - 正規表現による複数イベントの購読
3. `ActiveSupport::Notifications.subscribe(nil)` - すべてのイベントの購読

## 通知テンプレート

### イベントペイロード

| 項目 | 内容 |
|-----|------|
| イベント名 | `broadcast.action_cable` |
| 名前空間 | `action_cable` |
| ペイロード形式 | Ruby Hash |

### ペイロード構造

```ruby
{
  broadcasting: "chat_room_1",              # ブロードキャストチャンネル名（String）
  message: { body: "Hello, World!" },       # 配信するメッセージ（Hash/Object）
  coder: ActiveSupport::JSON                # エンコーダー（Module/Class）
}
```

### 添付ファイル

該当なし（計装イベントには添付ファイルは含まれない）

## テンプレート変数

| 変数名 | 説明 | データ取得元 | 必須 |
|--------|------|-------------|-----|
| `:broadcasting` | ブロードキャスト先のチャンネル名 | `broadcaster.broadcasting` | Yes |
| `:message` | 配信するメッセージのハッシュ | `broadcast` メソッドの引数 | Yes |
| `:coder` | メッセージのエンコーダー | `broadcaster.coder`（デフォルト: `ActiveSupport::JSON`） | Yes |

## 送信トリガー・条件

### トリガー一覧

| トリガー種別 | トリガーイベント | 送信条件 | 説明 |
|------------|----------------|---------|------|
| メソッド呼び出し | ブロードキャスト実行 | 常に送信 | `Broadcaster#broadcast` が呼び出されると必ず発行 |

### 送信抑止条件

| 条件 | 説明 |
|-----|------|
| なし | このイベントには送信抑止条件はない。broadcastメソッドが呼び出されれば必ず発行される |

## 処理フロー

### 送信フロー

```mermaid
flowchart TD
    A[ActionCable.server.broadcast呼び出し] --> B[broadcaster_for取得]
    B --> C[Broadcaster#broadcast実行]
    C --> D[payload構築]
    D --> E[ActiveSupport::Notifications.instrument]
    E --> F[broadcast.action_cableイベント開始]
    F --> G[メッセージエンコード]
    G --> H[PubSub配信]
    H --> I[broadcast.action_cableイベント終了]
    I --> J[サブスクライバーへ通知]
    J --> K[終了]
```

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

### 参照テーブル一覧

該当なし（計装イベント自体はデータベースを参照しない）

### 更新テーブル一覧

該当なし（計装イベント自体はデータベースを更新しない）

注：ブロードキャストされるメッセージの内容によっては、送信前にデータベースからデータを取得している可能性がある。

## エラー処理

### エラーケース一覧

| エラー種別 | 発生条件 | 対処方法 |
|----------|---------|---------|
| サブスクライバーエラー | サブスクライバー内で例外が発生 | エラーは伝播せず、他のサブスクライバーの処理は継続 |
| エンコードエラー | メッセージのJSONエンコードに失敗 | 例外がブロック内で発生し、イベント終了時に記録 |
| PubSubエラー | Redis等のPubSubシステムへの接続失敗 | 例外がブロック内で発生し、イベント終了時に記録 |

### リトライ仕様

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

## 配信設定

### レート制限

| 項目 | 内容 |
|-----|------|
| 1分あたり上限 | なし（ブロードキャスト呼び出しごとに発行） |
| 1日あたり上限 | なし |

### 配信時間帯

制限なし（ブロードキャストが実行されるタイミングで即座に発行）

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

- ペイロードの `:message` にはブロードキャストされるメッセージの内容が含まれる。これには機密情報（ユーザーデータ、トークン等）が含まれる場合がある
- サブスクライバーでログ出力やメトリクス送信を行う際は、機密情報のマスキングやフィルタリングを検討すること
- `:broadcasting` チャンネル名からユーザーIDや部屋ID等の情報が推測される可能性があるため、ログの保管・アクセス管理に注意すること

## 備考

- このイベントはブロードキャストのサーバー側での配信処理を計測する
- クライアントへの実際の配信（WebSocket経由）の成否は別途監視が必要
- 高頻度のブロードキャストがある場合、サブスクライバーでの処理がボトルネックにならないよう注意

---

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

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

### 推奨読解順序

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

まず、イベントのペイロード構造を理解することが重要。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | broadcasting.rb | `actioncable/lib/action_cable/server/broadcasting.rb` | ペイロードの構築（55行目）を確認 |

**読解のコツ**: `payload` ハッシュがどのようなキーと値を持つかを確認する。`:broadcasting`, `:message`, `:coder` の3つのキーが設定される。

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

処理の起点となるメソッドを特定。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | broadcasting.rb | `actioncable/lib/action_cable/server/broadcasting.rb` | `Broadcaster#broadcast` メソッド（52-59行目）がイベント発行の起点 |

**主要処理フロー**:
1. **52行目**: `broadcast` メソッドの定義開始
2. **53行目**: ログ出力（デバッグレベル）
3. **55行目**: ペイロードの構築（broadcasting, message, coder）
4. **56行目**: `ActiveSupport::Notifications.instrument` によるイベント発行
5. **57行目**: coderによるメッセージエンコード
6. **58行目**: PubSubシステムへの配信

#### Step 3: Broadcasterの生成を理解する

Broadcasterオブジェクトがどのように生成されるかを確認。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | broadcasting.rb | `actioncable/lib/action_cable/server/broadcasting.rb` | `broadcaster_for` メソッド（40-42行目）でBroadcaster生成 |
| 3-2 | broadcasting.rb | `actioncable/lib/action_cable/server/broadcasting.rb` | `broadcast` メソッド（33-35行目）でbroadcaster_forを使用 |

**主要処理フロー**:
- **33-35行目**: 公開API `broadcast` メソッドが `broadcaster_for` を呼び出し、そのBroadcasterの `broadcast` を実行
- **40-42行目**: `Broadcaster` クラスのインスタンスを生成（server, broadcasting名, coderを渡す）

#### Step 4: Broadcasterクラスの内部構造を理解する

Broadcasterクラスの完全な実装を確認。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | broadcasting.rb | `actioncable/lib/action_cable/server/broadcasting.rb` | Broadcasterクラス定義（45-61行目） |

**主要処理フロー**:
- **46行目**: `attr_reader :server, :broadcasting, :coder` でアクセサ定義
- **48-50行目**: `initialize` でserver, broadcasting, coderを保持
- **52-59行目**: `broadcast` メソッドでイベント発行と配信を実行

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

```
ActionCable.server.broadcast("channel", message)     # 公開API呼び出し
    |
    +-- ActionCable::Server::Broadcasting#broadcast
            |
            +-- ActionCable::Server::Broadcasting#broadcaster_for("channel")
                    |
                    +-- Broadcaster.new(server, "channel", coder: ActiveSupport::JSON)
                            |
                            +-- Broadcaster#broadcast(message)
                                    |
                                    +-- server.logger.debug (ログ出力)
                                    |
                                    +-- ActiveSupport::Notifications.instrument("broadcast.action_cable")
                                            |
                                            +-- coder.encode(message)  # JSONエンコード
                                            |
                                            +-- server.pubsub.broadcast(broadcasting, encoded)
                                            |
                                            +-- サブスクライバーへの通知
```

### データフロー図

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

ブロードキャスト名 ────────┐
                           │
メッセージハッシュ ────────┼──▶ Broadcaster#broadcast ──────────▶ broadcast.action_cable イベント
                           │           │
コーダー（JSON等）─────────┘           │
                                       ▼
                           ActiveSupport::Notifications.instrument
                                       │
                                       ├──▶ coder.encode(message)
                                       │
                                       └──▶ server.pubsub.broadcast
                                                   │
                                                   ▼
                           ┌───────────────────────────────────────────┐
                           │          PubSub システム                  │
                           │  (Redis, PostgreSQL, Async等)            │
                           └───────────────────────────────────────────┘
                                       │
                                       ▼
                           ┌───────────────────────────────────────────┐
                           │     購読中のWebSocketクライアント         │
                           └───────────────────────────────────────────┘
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| broadcasting.rb | `actioncable/lib/action_cable/server/broadcasting.rb` | ソース | ブロードキャスト機能、イベント発行元 |
| base.rb | `actioncable/lib/action_cable/server/base.rb` | ソース | ActionCable サーバー基底クラス |
| pubsub_adapter.rb | `actioncable/lib/action_cable/subscription_adapter/` | ソース | PubSubアダプター（Redis等） |
| active_support_instrumentation.md | `guides/source/active_support_instrumentation.md` | ドキュメント | 公式計装ガイド（122-129行目） |
| broadcasting_test.rb | `actioncable/test/server/broadcasting_test.rb` | テスト | ブロードキャスト機能のテスト |
