27 ライブ・イベントの使用
この章の内容は次のとおりです。
- ライブ・イベントの概要
Coherenceでは、データ・グリッドに対する操作を実行する際にクラスタ内での拡張を可能にするイベント・プログラミング・モデルが提供されます。 - ライブ・イベント・タイプの理解
イベント・タイプは、監視可能なクラスタ操作の発生を表します。 - ライブ・イベントの処理
アプリケーションは、イベント・インターセプタを使用してライブ・イベントを処理します。
親トピック: データ・グリッド操作の実行
ライブ・イベントの概要
-
パーティション・キャッシュ・イベント - キャッシュ内の一連のエントリに対して実行されている操作を表す一連のイベント。パーティション・キャッシュ・イベントには、エントリ・イベントとエントリ・プロセッサ・イベントの両方が含まれます。エントリ・イベントは、キャッシュのエントリの挿入、削除および更新に関連しています。エントリ・プロセッサ・イベントは、エントリ・プロセッサの実行に関連しています。
-
パーティション・キャッシュ・ライフサイクル・イベント – キャッシュの作成、破棄、キャッシュからのすべてのエントリのクリアの操作を表す一連のイベント。
-
パーティション・サービス・イベント - パーティション・サービスによって実行されている操作を表す一連のイベント。パーティション・サービス・イベントには、パーティション転送イベントとパーティション・トランザクション・イベントの両方が含まれます。パーティション転送イベントは、クラスタ・メンバー間のパーティションの移動に関連しています。パーティション・トランザクション・イベントは、複数のキャッシュにまたがる可能性がある変更に関連し、単一のリクエストのコンテキスト内で実行されます。
-
ライフサイクル・イベント -
ConfigurableCacheFactory
インスタンスのアクティブ化および破棄を表す一連のイベント。 -
フェデレーション・イベント – フェデレーション・サービスによって実行されている操作を表す一連のイベント。フェデレーション・イベントには、フェデレーテッド接続イベントとフェデレーテッド変更イベントの両方が含まれます。フェデレーテッド接続イベントは、フェデレーテッド参加者の相互作用に関連し、フェデレーテッド変更イベントはキャッシュ更新に関連します。
アプリケーションは、イベントを使用するためにイベント・インターセプタを作成および登録します。イベント・インターセプタは、イベントを処理し、必要に応じて任意のカスタム・ロジックを実装します。イベントには、そのイベントの受信時に可変アクションを実行できるかどうかを制御する様々なルールがあります。
親トピック: ライブ・イベントの使用
ライブ・イベント・タイプの理解
この項には次のトピックが含まれます:
- パーティション・キャッシュ・イベントの理解
- パーティション・キャッシュ・ライフサイクル・イベントの理解
- パーティション・サービス・イベントの理解
- ライフサイクル・イベントの理解
- フェデレーション・イベントの理解
親トピック: ライブ・イベントの使用
パーティション・キャッシュ・イベントの理解
パーティション・キャッシュ・イベントは、キャッシュ内の一連のエントリに対して実行される操作を表します。パーティション・キャッシュ・イベントには、エントリ・イベント(EntryEvent
)とエントリ・プロセッサ・イベント(EntryProcessorEvent
)が含まれます。これらのイベントは、com.tangosol.net.events.partition.cache
パッケージ内で定義されます。
この項には次のトピックが含まれます:
エントリ・イベント
エントリ・イベントは、キャッシュのエントリの挿入、削除および更新の操作を表します。プリコミット・エントリ・イベント(INSERTING
、REMOVING
およびUPDATING
)は操作が実行される前に発生し、エントリに対する変更を許可します。エントリを変更する際は、次の事項が当てはまります。
-
プリコミット・エントリ・イベントに対して登録されているイベント・インターセプタが同期して呼び出されます。
-
同時更新を防止するために、イベントの処理中は各エントリに対してロックが保持されます。
-
例外がスローされると、操作がコミットされなくなります。
ポストコミット・エントリ・イベント(INSERTED
、REMOVED
およびUPDATED
)は、操作が実行された後に、イベントの発生と同じ順序で発生します。ポストコミット・イベントは、エントリがそれ以降変更できないことを示します。ポストコミット・エントリ・イベントのイベント・インターセプタは、非同期に処理されます。
表27-1は、エントリ・イベント・タイプを示しています。
表27-1 エントリ・イベント
イベント・タイプ | 説明 |
---|---|
|
1つ以上のエントリが、キャッシュに挿入されようとしていることを示します。 |
|
1つ以上のエントリが、キャッシュに挿入されたことを示します。 |
|
1つ以上のエントリが、キャッシュから削除されようとしていることを示します。 |
|
1つ以上のエントリが、キャッシュから削除されたことを示します。 |
|
1つ以上のエントリが、キャッシュで更新されようとしていることを示します。 |
|
1つ以上のエントリが、キャッシュで更新されたことを示します。 |
親トピック: パーティション・キャッシュ・イベントの理解
エントリ・プロセッサ・イベント
エントリ・プロセッサ・イベントは、一連のバイナリ・エントリに対するエントリ・プロセッサの実行を表します。プリコミット・エントリ・プロセッサ・イベント(EXECUTING
)は、エントリ・プロセッサが実行される前に発生し、エントリ・プロセッサ・インスタンスに対する変更を許可します。エントリ・プロセッサを変更する際は、次の事項が当てはまります。
-
プリコミット・エントリ・プロセッサ・イベントに対して登録されているイベント・インターセプタは、処理中のエントリを変更でき、変更が永続的であると予想します。
-
プリコミット・エントリ・プロセッサ・イベントに対して登録されているイベント・インターセプタが同期して呼び出されます。
-
エントリ・プロセッサは複数のスレッドで共有できます。したがって、エントリ・プロセッサを変更するときはスレッド・セーフティを確保してください。
-
同時更新を防止するために、イベントの処理中は各エントリに対してロックが保持されます。
-
例外がスローされると、エントリ・プロセッサが実行されなくなります。
ポストコミット・エントリ・プロセッサ・イベント(EXECUTED
)は、エントリ・プロセッサが実行された後に、イベントの発生と同じ順序で発生します。ポストコミット・イベントは、エントリがそれ以降変更できないことを示します。ポストコミット・エントリ・プロセッサ・イベントのイベント・インターセプタは、非同期に処理されます。
表27-2は、エントリ・プロセッサ・イベント・タイプを示しています。
表27-2 エントリ・プロセッサ・イベント
イベント・タイプ | 説明 |
---|---|
|
エントリ・プロセッサが、一連のエントリに対して実行されようとしていることを示します。 |
|
エントリ・プロセッサが、一連のエントリに対して実行されたことを示します。 |
親トピック: パーティション・キャッシュ・イベントの理解
パーティション・キャッシュ・ライフサイクル・イベントの理解
パーティション・キャッシュ・ライフサイクル・イベント(CacheLifecycleEvent
)は、パーティション・キャッシュの作成、破棄および切捨てを表します。これらのイベントは、com.tangosol.net.events.partition.cache
パッケージ内で定義されます。
パーティション・キャッシュ・ライフサイクル・イベントは、パーティション・キャッシュの作成、破棄(NamedCache.destory
)または切捨て(NamedCache.truncate)
後に発生します。TRUNCATED
イベントには、キャッシュから削除されるエントリは含まれません。
表27-3 パーティション・キャッシュ・ライフサイクル・イベント
イベント・タイプ | 説明 |
---|---|
|
指定されたキャッシュの記憶域が作成されたことを示します。 |
|
指定されたキャッシュの記憶域が破棄されたことを示します。 |
|
指定されたキャッシュのすべてのマッピングが記憶域から削除されたことを示します。 |
親トピック: ライブ・イベント・タイプの理解
パーティション・サービス・イベントの理解
パーティション・サービス・イベントは、パーティション・サービスによって実行されている操作を表します。パーティション・サービス・イベントには、転送イベント(TransferEvent
)、トランザクション・イベント(TransactionEvent
)および非請求コミット・イベント(UnsolicitedCommitEvent
)が含まれます。これらのイベントは、com.tangosol.net.events.partition
パッケージ内で定義されます。
この項には次のトピックが含まれます:
転送イベント
パーティション・サービス転送イベントは、記憶域が有効なメンバー間のパーティションの転送を表します。イベントには、転送が実行されるサービス名、パーティションID、転送に関与するクラスタ・メンバー、およびキャッシュ名とエントリのマップが含まれています。これらのエントリは変更できません。
ノート:
転送イベントは、転送されるパーティションに対する操作をすべてブロックするロックが、そのパーティションに対して保持されている間に発生します。
表27-4は、遷移イベント・タイプを示しています。
表27-4 遷移イベント
イベント・タイプ | 説明 |
---|---|
|
一連のエントリが、現在のメンバーから転送中であることを示します。 |
|
一連のエントリが、現在のメンバーに転送されたこと、または現在のメンバーによってリストアされたことを示します。 |
親トピック: パーティション・サービス・イベントの理解
トランザクション・イベント
パーティション・サービス・トランザクション・イベントは、単一のサービス・リクエストのコンテキストで行われる、(場合によっては複数のキャッシュからの)バイナリ・エントリに対する変更を表します。プリコミット・トランザクション・イベント(COMMITTING
)は、操作が実行される前に発生し、エントリに対する変更を許可します。エントリを変更する際は、次の事項が当てはまります。
-
同時更新を防止するために、イベントの処理中は各エントリに対してロックが保持されます。
-
例外がスローされると、操作がコミットされなくなります。
ポストコミット・トランザクション・イベント(COMMITTED
)は、操作が実行された後に発生します。ポストコミット・イベントは、エントリがそれ以降変更できないことを示します。
表27-5は、トランザクション・イベント・タイプを示しています。
表27-5 トランザクション・イベント
イベント・タイプ | 説明 |
---|---|
|
エントリが、それぞれのキャッシュに挿入されようとしていることを示します。 |
|
エントリが、それぞれのキャッシュに挿入されたことを示します。 |
親トピック: パーティション・サービス・イベントの理解
非請求コミット・イベント
パーティション・サービスの非請求コミット・イベントは、パーティション・サービスに直接引き起こされて(請求されて)いない、キャッシュに対して実行されたすべての監視された変化に関連する変更を意味します。これらのイベントは、変更を発生させたバッキング・マップの削除あるいは参照など、バッキング・マップにより内的に起きた変更による場合もあります。イベントには、複数のバッキング・マップにまたがる可能性もある、すべての修正済エントリが含まれます。これらのエントリは変更できません。
表27-6に、非請求コミット・イベントのタイプを示します。
表27-6 トランザクション・イベント
イベント・タイプ | 説明 |
---|---|
|
エントリが、それぞれのキャッシュに挿入されたことを示します。 |
親トピック: パーティション・サービス・イベントの理解
ライフサイクル・イベントの理解
ライフサイクル・イベント(LifecycleEvent
)は、ConfigurableCacheFactory
インスタンスに対して発生したアクションを表します。これらのイベントは、com.tangosol.net.events.application
パッケージ内で定義されます。
ACTIVATED
イベントは、キャッシュ・ファクトリに関連付けられているすべてのサービスが起動された後に発生します。これらのサービスはキャッシュ構成ファイル内で定義され、自動的に起動されるように構成する必要があります。DISPOSING
イベントは、すべてのサービスが停止されて、すべてのリソースが解放される前に発生します。DISPOSING
イベントを処理するイベント・インターセプタは、サービスが停止される前に通知を受け取ります。ConfigurableCacheFactory
インスタンスのアクティブ化および破棄は1回のみ行うことができます。
ノート:
ライフサイクル・イベントは、ConfigurableCacheFactory
実装でライフサイクル・メソッドをコールするスレッドと同じスレッドによって、イベント・インターセプタにディスパッチされます。このスレッドは同期化されることがあります。イベント・インターセプタは、同じConfigurableCacheFactory
オブジェクトで、生成されたスレッドが同期化を行わないようにする必要があります。
表27-7は、ライフサイクル・イベント・タイプを示しています。
表27-7 ライフサイクル・イベント
イベント・タイプ | 説明 |
---|---|
|
|
|
|
親トピック: ライブ・イベント・タイプの理解
フェデレーション・イベントの理解
フェデレーション・イベントは、フェデレーション・サービスによって実行されている操作を表す一連のイベントを表します。フェデレーション・イベントには、フェデレーテッド接続イベント(FederatedConnectionEvent
)、フェデレーテッド変更イベント(FederatedChangeEvent
)、およびフェデレーテッド・パーティション・イベント(FederatedPartitionEvent
)が含まれます。これらのイベントは、com.tangosol.net.events.federation
パッケージ内で定義されます。
この項には次のトピックが含まれます:
フェデレーテッド接続イベント
フェデレーテッド接続イベントは、フェデレーテッド・サービスの参加者間の通信を表します。
ノート:
フェデレーテッド接続イベントは、イベントが発生したスレッドと同じスレッド上で発生します。これらのイベントを処理するインターセプタでは、ブロッキング操作を実行しないでください。
表27-8に、フェデレーテッド接続イベントのタイプを示します。
表27-8 フェデレーテッド接続イベント
イベント・タイプ | 説明 |
---|---|
|
参加者との接続が開始されようとしていることを示します。 |
|
参加者が接続されていないことを示します。 |
|
参加者がバックログされていることを示します。参加者がリモートの場合は、リモート参加者が処理できない量の作業があることを示します。参加者がローカルの場合は、この参加者が処理できない量の作業があることを示します。 |
|
参加者がバックログされなくなったことを示します。 |
|
変更をリモート参加者に適用している際にエラーが発生したか、接続の最大試行回数に達したことを示します。 |
親トピック: フェデレーション・イベントの理解
フェデレーテッド変更イベント
フェデレーテッド変更イベントは、フェデレーションのローカル・クラスタ参加者で発生した変更のトランザクション・ビューを表します。トランザクションはパーティション用、つまり、単一のパーティションに属するすべての変更が単一のFederatedChangeEvent
オブジェクトで取得されます。
ノート:
統合操作は、フェデレーション変更イベントには含まれません。
フェデレーテッド変更イベントでは、キャッシュ・エントリに対する変更がコミットされる前に、その変更を許可するかどうかを決定することで、競合解決が可能になります。Oracle Coherenceの管理のフェデレーテッド変更イベントの処理を参照してください。
エントリを変更する際は、次の事項が当てはまります。
-
同時更新を防止するために、イベントの処理中は各エントリに対してロックが保持されます。
-
例外がスローされると、操作がコミットされなくなります。
表27-9に、フェデレーテッド変更イベントのタイプを示します。
表27-9 フェデレーテッド変更イベント
イベント・タイプ | 説明 |
---|---|
|
エントリがローカル参加者のキャッシュに挿入されることを示します。 |
|
他の参加者からのエントリがローカル参加者のキャッシュに挿入されることを示します。 |
|
エントリがリモート参加者にレプリケートされることを示します。 |
親トピック: フェデレーション・イベントの理解
フェデレーテッド・パーティション・イベント
フェデレーテッド・パーティション・イベントは、フェデレーション中のパーティションのフェデレーション状態の変化を表します。
ノート:
このイベントは、パーティションごとにディスパッチされます。
表27-10に、フェデレーテッド・パーティション・イベントのタイプを示します。
表27-10 フェデレーテッド・パーティション・イベント
イベント・タイプ | 説明 |
---|---|
|
|
|
|
親トピック: フェデレーション・イベントの理解
ライブ・イベントの処理
この項には次のトピックが含まれます:
イベント・インターセプタの作成
イベント・インターセプタを作成するには、EventInterceptor
インタフェースを実装します。インタフェースはジェネリクスを使用して定義し、このインタフェースにより、汎用タイプのイベントをタイプ・パラメータとして指定してイベントをサブスクライブできるようになります。継承されたonEvent
メソッドは、イベントの受信時に必要な処理を実行する機能を提供します。次の例は、すべての転送イベントをサブスクライブするもので、例27-1からの抜粋です。
public class RedistributionInterceptor implements EventInterceptor<TransferEvent> public void onEvent(TransferEvent event) { ...
@Interceptor
注釈を使用すると、イベントを特定のイベント・タイプにさらに制限でき、インターセプタのさらなる構成も可能です。次の例では、インターセプタ識別子を定義し、イベントを転送のDEPARTING
イベントのみに制限します。
@Interceptor(identifier = "redist", transferEvents = TransferEvent.Type.DEPARTING) public class RedistributionInterceptor implements EventInterceptor<TransferEvent> public void onEvent(TransferEvent event) { ...
@Interceptor
注釈には、次の属性が含まれます。
-
identifier
– インターセプタの一意の識別子を指定します。識別子は、キャッシュ構成ファイルでインターセプタ・クラスを登録するときにオーバーライドできます。この属性はオプションです。この属性を省略した場合は、イベント・インフラストラクチャによって一意の名前が自動的に生成されます。 -
entryEvents
- インターセプタがサブスクライブするエントリ・イベント・タイプの配列を指定します。 -
entryProcessorEvents
- インターセプタがサブスクライブするエントリ・プロセッサ・イベント・タイプの配列を指定します。 -
transferEvents
- インターセプタがサブスクライブする転送イベント・タイプの配列を指定します。 -
transactionEvents
- インターセプタがサブスクライブするトランザクション・イベント・タイプの配列を指定します。 -
unsolicitedEvents
- インターセプタがサブスクライブする非請求イベント・タイプの配列を指定します。 -
cacheLifecycleEvent
- インターセプタがサブスクライブするキャッシュ・ライフサイクル・イベント・タイプの配列を指定します。 -
federatedChangeEvents
- インターセプタがサブスクライブするフェデレーション変更イベント・タイプの配列を指定します。 -
federatedConnectionEvent
- インターセプタがサブスクライブするフェデレーション接続イベント・タイプの配列を指定します。 -
order
- このインターセプタを、インターセプタの連鎖の前に配置するかどうかを指定します。イベント・インターセプタの連鎖を参照してください。有効な値はLOW
とHIGH
です。HIGH
の値は、そのインターセプタを、インターセプタの連鎖の前に配置することを示します。LOW
の値は、順序付けのプリファレンスはないことを示します。デフォルト値はLOW
です。この順序は、キャッシュ構成ファイルでインターセプタ・クラスを登録するときにオーバーライドできます。
次の例は、すべての転送イベント・タイプ(DEPARTING
とARRIVED
の両方)をサブスクライブする基本的なイベント・インターセプタの実装を示しています。onEvent
メソッドは、単にパーティション・アクティビティを示すイベントを記録します。この例は、Coherenceの例の一部です。
ノート:
イベント・インスタンスは不変であり、それらのライフサイクルは基礎となるシステムによって制御されます。イベント・クラスの参照は、onEvent()
メソッドの複数の呼出しにわたって保持しないでください。
例27-1 イベント・インターセプタの実装例
package com.tangosol.examples.events; import com.tangosol.net.CacheFactory; import com.tangosol.net.events.EventInterceptor; import com.tangosol.net.events.annotation.Interceptor; import com.tangosol.net.events.partition.TransferEvent; @Interceptor(identifier = "redist") public class RedistributionInterceptor implements EventInterceptor<TransferEvent> { public void onEvent(TransferEvent event) { CacheFactory.log(String.format("Discovered event %s for partition-id %d from remote member %s\n", event.getType(), event.getPartitionId(), event.getRemoteMember()), CacheFactory.LOG_INFO); } }
親トピック: ライブ・イベントの処理
イベントのスレッディングの理解
イベント・インターセプタは、キャッシュ操作に大きな影響を与えることがあるため、基礎となるスレッドをブロックしないように注意してください。そのようにしないとそれらに影響を与えます。イベント・インターセプタを作成する場合は、プリコミット・イベント・タイプとポストコミット・イベント・タイプの両方に対する影響を注意深く考慮する必要があります。
ノート:
EventInterceptor
インスタンスは再利用できますが、複数のスレッドが同時にディスパッチできるように、それらのインスタンスは不変であるかスレッド・セーフである必要があります。
プリコミット・イベント
プリコミット・イベント・タイプは、キャッシュにエントリがコミットされる前に、イベント・インターセプタにエントリを変更することを許可します。インターセプタは、同期的に処理されるため、実行時間の長い操作(データベース・アクセスなど)を実行しないでください。それによってキャッシュ操作がブロックされたり遅くなることがあります。外部リソースの呼出しは、キャッシュ操作がブロックされるのを防ぐために常にできるかぎり速く返す必要があります。
動的スレッド・プールはパーティション・サービスに対して自動的に有効化されます。スレッド・プールによって、キャッシュ操作を処理する追加のスレッドが作成され、プリコミット・イベントを処理するイベント・インターセプタによる全体的な影響が軽減されますが、ブロックされる可能性は依然として存在します。分散キャッシュ定義内の<thread-count-min>
および<thread-count-max>
要素を使用して、スレッド・プールのサイズを明示的に設定します。表B-19を参照してください。
ポストコミット・イベント
ポストコミット・イベントは、イベント・インターセプタによるエントリの変更を許可しません。そのイベントは、イベントの発生と同じ順序で発生し、インターセプタは非同期で処理されます。実行時間の長い操作を実行するイベント・インターセプタは、リクエストのバックログを発生させる場合があり、それによって最終的にパフォーマンスが低下することがあります。ベスト・プラクティスは、Java Executorサービスを使用してそのような操作を別のスレッドで実行することです。
親トピック: ライブ・イベントの処理
イベント・インターセプタの登録
イベント・インターセプタは、キャッシュ構成ファイル内に登録されます。イベント・インターセプタは、特定のキャッシュまたはパーティション・サービスのいずれかに対して登録されます。特定のキャッシュに対して登録されたイベント・インターセプタは、そのキャッシュに関連するイベントのみを受信します。パーティション・サービスに対して登録されたイベント・インターセプタは、そのサービスによって管理されるキャッシュすべてのイベントを受信します。
ノート:
サービスレベルのイベント(転送イベント、トランザクション・イベント、フェデレーションなど)のイベント・インターセプタは、パーティション・サービスに対して登録する必要があり、特定のキャッシュに制限することはできません。
この項には次のトピックが含まれます:
- 特定のキャッシュに対するイベント・インターセプタの登録
- パーティション・サービスに対するイベント・インターセプタの登録
- キャッシュ構成ファクトリに対するイベント・インターセプタの登録
- カスタム登録の使用
- イベント・インターセプタの登録のガイドライン
親トピック: ライブ・イベントの処理
特定のキャッシュに対するイベント・インターセプタの登録
特定のキャッシュに対してインターセプタを登録するには、任意の数の<interceptor>
サブ要素を含む<interceptors>
要素を<cache-mapping>
要素内に含めます。各<interceptor>
要素には、<instance>
サブ要素を含め、EventInterceptor
インタフェースを実装する完全修飾クラス名を指定する必要があります。interceptor要素を参照してください。次の例では、MyInterceptor
というイベント・インターセプタ・クラスを登録します。
ノート:
キャッシュ・マップへのインターセプタの登録は、サービス・レベルのイベントではなく、キャッシュ・レベルのイベントのみが対象です。キャッシュ・マップでサービスレベルのイベント・インターセプタを登録すると、そのサービスに属するすべてのキャッシュでそのインターセプタがトリガーされます。
<caching-scheme-mapping> <cache-mapping> <cache-name>example</cache-name> <scheme-name>distributed</scheme-name> <interceptors> <interceptor> <name>MyInterceptor</name> <instance> <class-name> com.tangosol.examples.events.MyInterceptor </class-name> </instance> </interceptor> </interceptors> </cache-mapping> </caching-scheme-mapping>
親トピック: イベント・インターセプタの登録
パーティション・サービスに対するイベント・インターセプタの登録
パーティション・サービスに対してインターセプタを登録するには、任意の数の<interceptor>
サブ要素を含む<interceptors>
要素を<distributed-scheme>
要素内に含めます。各<interceptor>
要素には、<instance>
サブ要素を含め、EventInterceptor
インタフェースを実装する完全修飾クラス名を指定する必要があります。interceptorを参照してください。次の例では、例27-1で定義したRedistributionInterceptor
クラスを登録します。
<distributed-scheme> <scheme-name>distributed</scheme-name> <service-name>PartitionedService1</service-name> <backing-map-scheme> <local-scheme/> </backing-map-scheme> <autostart>true</autostart> <interceptors> <interceptor> <name>MyInterceptor</name> <instance> <class-name> com.tangosol.examples.events.RedistributionInterceptor </class-name> </instance> </interceptor> </interceptors> </distributed-scheme>
親トピック: イベント・インターセプタの登録
キャッシュ構成ファクトリに対するイベント・インターセプタの登録
ConfigurableCacheFactory
インスタンスに対してインターセプタを登録するには、任意の数の<interceptor>
サブ要素を含む<interceptors>
要素を<cache-config>
要素内に含めます。各<interceptor>
要素には、<instance>
サブ要素を含め、EventInterceptor
インタフェースを実装する完全修飾クラス名を指定する必要があります。interceptorを参照してください。次の例では、MyInterceptor
というイベント・インターセプタ・クラスを登録します。
<cache-config> <interceptors> <interceptor> <name>MyInterceptor</name> <instance> <class-name>com.tangosol.examples.events.MyInterceptor</class-name> </instance> </interceptor> </interceptors> ... </cache-config>
親トピック: イベント・インターセプタの登録
カスタム登録の使用
@Interceptor
注釈および汎用タイプは、イベント・インフラストラクチャがイベント・インターセプタを適切なイベント・ディスパッチャに登録するために使用されます。このメカニズムは、ほとんどのユースケースでは問題ありません。ただし、高度なユースケースでは、イベント・インターセプタはEventDispatcherAwareInterceptor
インタフェースを実装するように選択できるため、必要なイベント・ディスパッチャにイベント・インターセプタを手動で登録します。
introduceEventDispatcher
メソッドには、インターセプタが登録されるイベント・ディスパッチャが含まれます。さらに必要に応じて、ディスパッチャのメソッドを使用して、インターセプタの追加および削除、特定のイベント・タイプの制限、およびインターセプタの構成を行います。次の例は、インターセプタを明示的に登録して、エントリのINSERTING
イベントをサブスクライブし、インターセプタが最初にコールされて通知されるように順序付けを構成するカスタム実装を示しています。
public void introduceEventDispatcher(String sIdentifier, EventDispatcher dispatcher) { dispatcher.addEventInterceptor(sIdentifier, this, new HashSet(Arrays.asList(EntryEvent.Type.INSERTING)), true); }
ノート:
インターセプタが注釈を使用しないで構成されている場合、キャッシュ構成ファイルを使用してその構成をオーバーライドすることはできません。
インターセプタは、InterceptorRegistry
APIを使用してプログラムによって登録することもできます。インターセプタを登録すると、現在登録されているイベント・ディスパッチャと将来のイベント・ディスパッチャのすべてにそのインターセプタが導入されます。インターセプタは、前述の例に示したようにintroduceEventDispatcher
メソッドを使用して、ディスパッチャにバインドするかどうかを決定できます。
InterceptorRegistry
APIはConfigurableCacheFactory
インタフェースから使用でき、getInterceptorRegistry
メソッドを使用してコールします。このAPIは、宣言でインターセプタを登録するときのキャッシュ構成ファイルとあわせて使用できます。このAPIは、プログラムによってインターセプタを追加するためにカスタムDefaultCacheServer
実装と一緒によく使用され、InvocationService
インタフェースを使用する場合にインターセプタを選択によって登録するために使用されます。次の例では、インターセプタを登録します。
CacheFactory.getConfigurableCacheFactory().getInterceptorRegistry() .registerEventInterceptor(new MyEventIntercepor());
親トピック: イベント・インターセプタの登録
イベント・インターセプタの登録のガイドライン
インターセプタは、同じサービスに対して複数の分散スキームで登録できます。また、分散スキームがスキーム参照を使用する場合、インターセプタ・クラスを継承できます。いずれの場合も、インターセプタ・クラスはサービスに登録されます。
ほとんどの場合、複数のインターセプタ・クラスを登録しても問題はありません。ただし、特定のサービスに対して同じインターセプタ・クラスおよび識別子名の重複が発生する可能性が高くなります。重複によって登録エラーが発生しないように、次のガイドラインに従ってください。
-
識別子名が一意であるか、識別子名を定義しない場合は、1つの分散スキームや同じサービスの複数のスキームでインターセプタ・クラスを複数回複製できます。後者の場合は、イベント・インフラストラクチャによって一意の名前が自動的に生成されます。
-
同じ識別子名のインターセプタ・クラスは(複製したものもそうでないものも)分散スキームで複数回登録することはできず、登録エラーが発生します。
-
スキーム参照によって継承されたインターセプタ・クラスは、参照の連鎖内で異なるサービス名ごとに1回ずつ登録されます。
親トピック: イベント・インターセプタの登録
イベント・インターセプタの連鎖
この項には次のトピックが含まれます:
イベント・インターセプタの連鎖の概要
同じイベント・タイプに対して登録されている複数のイベント・インターセプタは、イベントのディスパッチを行うスレッドによってシリアルにコールされます。この方法でインターセプタを連鎖する機能により、カスタム・ロジックが連鎖内の他のインターセプタの結果に基づいて実行される複雑な処理シナリオが可能になります。連鎖ないの各イベント・インターセプタは次のことを実行できます。
-
イベントと関連付けられているデータを変更すること(許可されている場合)。たとえば、
INSERTING
、UPDATING
、REMOVING
などのエントリ・イベントのプリコミット操作によってデータを変更できます。 -
例外をスローしてプリコミット操作を拒否すること。
-
パーティションレベルのトランザクションに新しいエントリを参加させること。
-
連鎖内の後続のイベント・インターセプタによる副作用の結果を監視すること。インターセプタ連鎖がプリコミット記憶域イベントと関連付けられている場合、結果を監視する機能により、処理を拒否するための2番目の機会が提供されます。
後続のイベント・インターセプタの副作用の監視は、
Event.nextInterceptor
メソッドを使用して実行します。このメソッドが返されたとき、それは後続のイベント・インターセプタがすべて実行され、そのイベントに関連付けらている状態に対する変更をインターセプトできることを示します。Event
オブジェクトは、イベントの処理に関する状態を保持します。イベントは、連鎖内にイベント・インターセプタが存在するかぎり、各イベント・インターセプタのonEvent
メソッドをコールします。イベント・インターセプタ自体がEvent.nextInterceptor
メソッドをコールする場合、連鎖内の次のイベント・インターセプタが起動されて実行されます。イベント・インターセプタが返されると、イベント自体が連鎖内の次のイベント・インターセプタのonEvent
メソッドをトリガーします。どちらの場合も、すべてのイベント・インターセプタが実行されますが、nextInterceptor
メソッドをコールすることを選択すると、発生した副作用に基づいてアクションを実行するオプションがあります。
親トピック: イベント・インターセプタの連鎖
イベント・インターセプタの連鎖順序の指定
連鎖内のイベント・インターセプタは、登録された順序に基づいて実行されます。@Interceptor
注釈のorder
属性を使用して、インターセプタを連鎖の前に配置するかどうかを指定します。HIGH
の値では、そのインターセプタが連鎖の前に配置されます。LOW
の値は、デフォルト値であり、順序付けのプリファレンスはないことを示します。たとえば:
@Interceptor(identifier = "MyInterceptor", entryEvents = {Type.INSERTING, Type.INSERTED} order = Order.HIGH) public class MyInterceptor implements EventInterceptor<EntryEvent<?,?>> ...
順序は、キャッシュ構成ファイルでイベント・インターセプタを登録するときに宣言で指定することもでき、それによってイベント・インターセプタ・クラスで指定されているorder
属性がオーバーライドされます。
キャッシュ構成ファイルでインターセプタの順序を指定するには、<interceptor>
要素内に、HIGH
またはLOW
に設定した<order>
要素を含めます。たとえば:
<interceptors> <interceptor> <name>MyInterceptor</name> <order>HIGH</order> <instance> <class-name>package.MyInterceptor</class-name> </instance> </interceptor> <interceptor> <name>MySecondInterceptor</name> <instance> <class-name>package.MySecondInterceptor</class-name> </instance> </interceptor> </interceptors>
親トピック: イベント・インターセプタの連鎖