in some cases the processing can take some time (in the observer method). a common trick is to use an ejb + @Asynchronous for the observer-method. with that the event-source can continue and the observer operates in a new thread.
however, that isn't enough if there is a huge amount of such events. for use-cases like that i've prototyped an add-on for apache deltaspike which allows to use disruptor for firing and observing events. it includes a simple qualifier support, however, it doesn't provide an 1:1 implementation of the cdi event rules. it can be used the same way as cdi events:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class DefaultEventBroadcastingTest | |
{ | |
@Inject | |
private AsynchronousEvent<MyEvent> myAsyncEvent; | |
public void fireAsyncEvent() | |
{ | |
this.myAsyncEvent.fire(new MyEvent(/*...*/)); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@ApplicationScoped | |
public class AsyncObserver | |
{ | |
public void onEvent(@ObservesAsynchronous MyEvent event) | |
{ | |
//... | |
} | |
} |
since the observer methods are invoked on the contextual-instance, cdi features like dependency-injection can be used as expected. the result is really nice. there is a huge difference in view of the pure event-processing performance of the events:
the result might look strange at the first view. however, the effects are quite clear. since the observer-logic in the demo is fast, the benefit of using @Asynchronous is lost. here the pure invocation of observers in ejbs is slower (than observers in a cdi-bean), because the container has to handle additional ejb features like transactions. the cdi bean as well as the stateful ejb is application-scoped and therefore only one (cached) instance is needed.
in the charts above it's hard to see, but the numbers show that tomee is faster in case of the deltaspike/disruptor add-on (due to the highly optimized proxies of openwebbeans 1.2.x) and as7 is a bit faster with dispatching standard cdi events.
currently the add-on works with tomee and as7 (tested with v7.2) and is available here. the repository also contains several tests, which illustrate the supported use-cases.