サービスイベントの管理
相互サービス通信の手段の 1 つは、直接的なピアツーピアコオペレーションとコラボレーションによるものです。これは明示的な起動としてすでに定義されているため、このような通信をサポートするために特別のメカニズムは必要ありません。
ただし、プラグアンドプレイアーキテクチャでは、サービスはより独立性が高く、ほかのサービスに認識されなくなります。これらの独立サービス間の相互サービス通信を簡単に行うには、これらのサービス間の情報を伝達し、無秩序な同期通信を管理するための一般的なメカニズムが必要です。
ほかのサービスに影響を与える重大なイベントがサービス内で発生した場合に、各サービスは、発生する可能性のあるサービスイベントを指定する必要があります。また、各サービスは、システム内で発生するほかの重大なイベントの通知を受け、これに対応するために、ほかのサービスのイベントのリスナーを確立する必要があります。
サービスイベントの登録
サービスは、開始時に wt.services.StandardManager を使用してイベントを登録できます。起動時の登録サービスイベントは、イベントをアクセス制御などのプロセスに知らせます。以下の例は、バージョン管理サービスのためにオーバーライドされた wt.services.StandardManager の registerEvents メソッドにイベントを登録する方法を示しています。
| より暗黙的なイベント登録の方法は、registerEvents メソッドで行う代わりに、最初に発生した時点でイベントが登録されるようにする方法です。イベントが発生すると、このイベントを購読しているすべてのリスナーが通知を受けます。 |
サービスイベントの購読
サービスがシステム内でのイベント発生の通知を受けるには、対象となる特定のサービスイベントを購読する必要があります。このためには、リスナーと対象のイベントを識別するキーと一緒に wt.services.ManagerService.addEventListener メソッドを起動する必要があります。
購読中に指定されたリスナーは、wt.events.KeyedEventListener インタフェースを実装する必要があります。これが、notifyEvent メソッドと notifyVetoableEvent メソッドを定義します。wt.services.ServiceEventListenerAdapter クラスは、リスナーが拡張できて通知に必要なメソッドだけをオーバーライドできるユーティリティとして提供されます。notifyEvent は、すべての購読のケースで使用される一般的なメソッドです。notifyVetoableEvent メソッドはより特化されています。これは、例外によってイベントの拒否手段を提供することを目的としています。
通常、イベントのリスナーは、内部クラスの匿名または名前指定インスタンスのどちらかを使用して実装されます。これにより、wt.events.KeyedEventListener インタフェースを実装せずに外部クラスを設計することができます。このため、リスナーインタフェースを実装せずにタイプが直接目的を反映し、外部クラスを純粋に保つことができます。以下は、performStartupProcess メソッドをオーバーライドし特定のイベントにリスナーを定義し追加する方法の例です。
サービスイベントの通知
特定のイベントを購読したすべてのリスナーのリストは、ManagerService によって維持されます。このリストは無秩序な方法で走査され、同期 Java メソッド起動機能を使用して各リスナーが順番に実行されます。リスナー通知メソッドは、イベントエミッターと同じスレッドとデータベーストランザクション内で実行されます。つまり、通知に応えてリスナーによって実行されるデータベースオペレーションは、イベントエミッターのトランザクションに含まれます。以下は、PersistenceManagerEvent.PREPARE_FOR_MODIFICATION のようなイベントの発送を示す例です。
サービスイベントの例外の処理
リスナーがイベントを拒否すると、例外が発生します。例外が発生すると、このイベントをすでに通知されている各リスナーは、例外を渡す、クリーンアップのために受理して再発生させる、または finally 節を実装してクリーンアップするのいずれかの方法でこの例外を処理できます。
先に説明したように、イベント通知はイベントエミッターと同じスレッドとトランザクションフレーム内で発送されます。つまり、イベントエミッターは、別のリスナーから拒否された場合に、行った任意のデータベース更新をロールバックする必要があります。以下の例はこのガイドラインを示しています。POST_STORE イベントが拒否されると、トランザクションを Null に設定した行には到達しないため、トランザクションがロールバックされる finally 節に制御が移ります。
サービスイベントの凡例
特定のサービスイベントの意味は、イベントの設計者が決定します。イベントには、後続の処理のためにイベントリスナーが必要とするすべての情報が含まれている必要があります。wt.events パッケージには、新しいイベントタイプを作成するために拡張可能な基本イベントクラス wt.events.KeyedEvent が含まれています。
一般的なイベント設計パターンには、プレイベントとポストイベントが含まれています。プレイベントは、リスナーにイベントが発生することを知らせるために使用されます。これらは、通常リスナーにイベントを確認し、場合によっては拒否する機会を与えることを目的としています。ポストイベントは、リスナーにイベントが終了したことを知らせるために使用されます。これらは、イベントの結果として、サービスがある種の事後処理を行う必要がある場合に有効です。すべてのイベントにプレイベントまたはポストイベントが必要な訳ではありません。イベントの唯一の定義は、発生したかどうかわからない特別な状態を示すために使用できます。