# 通知設計書 6-ActionListener通知

## 概要

本ドキュメントは、OpenSearchにおけるActionListener通知の設計仕様を記載する。ActionListenerは非同期アクションの成功（onResponse）または失敗（onFailure）を呼び出し元に通知するための汎用的なリスナーインターフェースであり、OpenSearch全体で広く利用される非同期通知の基盤である。

### 本通知の処理概要

ActionListener通知は、非同期に実行されるアクション（検索、インデックス操作、クラスタ管理操作等）の完了結果を呼び出し元に通知するための仕組みである。

**業務上の目的・背景**：OpenSearchは高スループットを実現するために、多くの操作を非同期で実行する。検索リクエスト、ドキュメントのインデックス、クラスタ管理操作など、ほぼすべての操作がActionListenerを通じて結果を返す。このインターフェースはOpenSearch全体の非同期処理パターンの基盤となっており、リクエストの受信からレスポンスの返却まで一貫した非同期通知モデルを提供する。

**通知の送信タイミング**：非同期アクションが完了した時点で通知が発生する。成功時にはonResponse()が呼ばれ、失敗時にはonFailure()が呼ばれる。どちらか一方のみが呼ばれることが期待される（保証はNotifyOnceListenerで実現）。

**通知の受信者**：ActionListener<Response>インターフェースを実装したコンポーネント。ジェネリクス型パラメータResponseにより、任意のレスポンス型に対応する。

**通知内容の概要**：onResponse()では型パラメータResponseで指定された応答オブジェクトが渡される。onFailure()ではExceptionオブジェクトが渡される。

**期待されるアクション**：受信者はonResponse()でアクションの成功結果を処理し、クライアントへの応答や後続処理を実行する。onFailure()では例外に応じたエラーハンドリング（エラー応答、リトライ、ログ記録など）を実行する。

## 通知種別

プロセス内コールバック通知（Javaインターフェースによるリスナーパターン。ジェネリクス対応）

## 送信仕様

### 基本情報

| 項目 | 内容 |
|-----|------|
| 送信方式 | 非同期（アクション完了スレッドから呼び出し） |
| 優先度 | 高（アクション結果の通知は即時処理が必要） |
| リトライ | 無し（リトライはアクション実装側の責任） |

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

アクション実行時に引数として渡されたActionListenerに対して通知する。1アクションに対して1リスナーが対応する。wrap()、map()、delegateFailure()等のユーティリティメソッドによりリスナーを合成・変換可能。

## 通知テンプレート

### メール通知の場合

本通知はプロセス内コールバックであるため、メール通知は該当しない。

| 項目 | 内容 |
|-----|------|
| 送信元アドレス | N/A |
| 送信元名称 | N/A |
| 件名 | N/A |
| 形式 | N/A |

### 本文テンプレート

```
N/A（Javaオブジェクトとして通知）
```

### 添付ファイル

| ファイル名 | 形式 | 条件 | 説明 |
|----------|------|------|------|
| N/A | N/A | N/A | 添付ファイルなし |

## テンプレート変数

| 変数名 | 説明 | データ取得元 | 必須 |
|--------|------|-------------|-----|
| response | アクションの成功応答 | アクション実装 | onResponse時 |
| exception | アクションの失敗例外 | アクション実装 | onFailure時 |

## 送信トリガー・条件

### トリガー一覧

| トリガー種別 | トリガーイベント | 送信条件 | 説明 |
|------------|----------------|---------|------|
| アクション成功 | 非同期アクションの正常完了 | 処理が成功すること | onResponse(response)が呼ばれる |
| アクション失敗 | 非同期アクションの例外発生 | 処理中に例外が発生すること | onFailure(exception)が呼ばれる |

### 送信抑止条件

| 条件 | 説明 |
|-----|------|
| 特になし | アクション完了時に必ず通知される |

## 処理フロー

### 送信フロー

```mermaid
flowchart TD
    A[非同期アクション開始] --> B{アクション結果}
    B -->|成功| C[listener.onResponse - response]
    B -->|失敗| D[listener.onFailure - exception]
    C --> E{onResponse内で例外?}
    E -->|Yes| F[listener.onFailure - exception]
    E -->|No| G[処理完了]
    D --> G
    F --> G
```

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

### 参照テーブル一覧

| テーブル名 | 用途 | 備考 |
|-----------|------|------|
| N/A | N/A | RDBは使用しない |

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

N/A

### 更新テーブル一覧

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

#### 送信ログテーブル

| 操作 | 項目（カラム名） | 更新値 | 備考 |
|-----|-----------------|-------|------|
| N/A | N/A | N/A | N/A |

## エラー処理

### エラーケース一覧

| エラー種別 | 発生条件 | 対処方法 |
|----------|---------|---------|
| アクション失敗 | アクション処理中の例外 | onFailure(exception)で通知 |
| onResponse内例外 | wrap()で作成されたリスナーのonResponse内で例外発生 | onFailure()に委譲 |
| 複数リスナーへの通知失敗 | ActionListener.onResponse(Iterable, response)で一部リスナーが例外をスロー | ExceptionsHelper.maybeThrowRuntimeAndSuppressで集約しスロー |

### リトライ仕様

| 項目 | 内容 |
|-----|------|
| リトライ回数 | 0（リトライはアクション実装側の責任） |
| リトライ間隔 | N/A |
| リトライ対象エラー | N/A |

## 配信設定

### レート制限

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

### 配信時間帯

制限なし

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

レスポンスオブジェクトにはクエリ結果やインデックスデータなどの機密情報が含まれる可能性がある。@PublicApi(since = "1.0.0")としてマークされており、プラグインからも利用可能。

## 備考

- @PublicApi(since = "1.0.0")として公開APIに指定されている
- ジェネリクス型パラメータ<Response>により任意の応答型に対応
- 豊富なユーティリティメソッドを提供：wrap(), map(), delegateFailure(), delegateResponse(), runAfter(), runBefore(), notifyOnce(), completeWith(), toBiConsumer(), noOp()
- wrap(CheckedConsumer, Consumer)でラムダ式から簡潔にリスナーを生成可能
- ActionListener.onResponse(Iterable, response)で複数リスナーへの一括通知が可能
- ActionListener.onFailure(Iterable, failure)で複数リスナーへの一括エラー通知が可能
- notifyOnce()でNotifyOnceListenerにラップし、二重通知を防止可能

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | ActionListener.java | `libs/core/src/main/java/org/opensearch/core/action/ActionListener.java` | onResponse/onFailureの2メソッド定義（行58, 63）、ユーティリティメソッド群（行74-365） |

**読解のコツ**: ActionListenerはインターフェースだが、多数のstaticユーティリティメソッドを持つ。wrap()（行74-93）が最も基本的なファクトリメソッドで、CheckedConsumerとConsumerからリスナーを生成する。

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

ActionListenerは汎用インターフェースであり、特定のエントリーポイントはない。各アクションの実装がリスナーを受け取り、処理完了時にコールバックする。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | ActionListener.java | `libs/core/src/main/java/org/opensearch/core/action/ActionListener.java` | wrap()メソッド（行74-93）でリスナー生成パターンを確認 |
| 2-2 | ActionListener.java | `libs/core/src/main/java/org/opensearch/core/action/ActionListener.java` | map()メソッド（行170-202）でレスポンス変換パターンを確認 |

**主要処理フロー**:
1. **行58**: `onResponse(Response response)` - 成功通知
2. **行63**: `onFailure(Exception e)` - 失敗通知
3. **行74-93**: `wrap(CheckedConsumer, Consumer)` - ラムダからリスナー生成
4. **行170-202**: `map(ActionListener, CheckedFunction)` - レスポンス変換
5. **行227-241**: `onResponse(Iterable, response)` - 一括成功通知
6. **行247-257**: `onFailure(Iterable, failure)` - 一括失敗通知
7. **行320-332**: `notifyOnce(ActionListener)` - 二重通知防止ラッパー

#### Step 3: 合成パターンを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | ActionListener.java | `libs/core/src/main/java/org/opensearch/core/action/ActionListener.java` | delegateFailure()（行127-140）、delegateResponse()（行103-116）、runAfter()（行263-283）、runBefore()（行291-314） |

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

```
アクション実行元
    |
    +-- ActionListener.wrap(onResponse, onFailure) ── リスナー生成
    |
    +-- アクション実行（リスナーを引数に渡す）
            |
            +-- [成功時] listener.onResponse(response)
            |
            +-- [失敗時] listener.onFailure(exception)

合成パターン:
    ActionListener.map(delegate, fn)
        +-- onResponse: fn.apply(response) → delegate.onResponse(mapped)
        +-- onFailure: delegate.onFailure(exception)
```

### データフロー図

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

アクションリクエスト ───▶ 非同期アクション実行
                              |
                     ┌────────┴────────┐
                     v                 v
              [成功] Response    [失敗] Exception
                     |                 |
                     v                 v
              onResponse()       onFailure()
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| ActionListener.java | `libs/core/src/main/java/org/opensearch/core/action/ActionListener.java` | ソース | リスナーインターフェース定義・ユーティリティ |
| NotifyOnceListener.java | `libs/core/src/main/java/org/opensearch/core/action/NotifyOnceListener.java` | ソース | 二重通知防止ラッパー |
| ExceptionsHelper.java | `libs/core/src/main/java/org/opensearch/ExceptionsHelper.java` | ソース | 例外集約ユーティリティ |
