IBM has raised the issue of event processing in a distributed
environment, and we (Red Hat) have promised to address this issue in
the revised public draft.
The Web Beans event bus provides a very nice way for stateful
components to synchronize their state (transactionally) with changes
that take place in the application. Event processing is *much* more
important in an environment with stateful object such as SFSBs than it
is in an environment with only stateless objects such as SLSBs or
Spring beans. Furthermore, event processing must be aware of the
transaction completion lifecycle (many applications today have bugs
when transaction rollbacks occur). Therefore, I believe that event
processing is an essential feature of Web Beans.
However, the event bus we have today is a purely local construct and
does not help when the application is distributed across multiple
cluster nodes or multiple physical tiers.
Designing a distributed event bus would potentially be a very
difficult undertaking, with so many issues to think about: QoS,
asynchronicity, transactionality, routing, etc. Fortunately, JMS
already has the features we need, and is what is sometimes used today
to solve the problems we're talking about:
* asynchronous, distributed semantics
* a notion of both 1-of-N and N-of-N semantics (queues and topics)
* a notion of logical channels (to allow routing of events between
tiers and applications)
* support for a range of QoS semantics
* transactionality
Furthermore, JMS is well-understood and well-supported.
If the spec simply defines that events were distributed via JMS,
absolutely nothing would stop vendors from also supporting alternative
distribution mechanisms as proprietary extensions (for example, in
JBoss we could provide support for JGroups).
And when EE finally gets a WorkManager API, a future version of Web
Beans could also define that distribution of local asynchronous events
is via the WorkManager.
The application developer would not be exposed to the JMS APIs. The
actual interaction with JMS would be handled by the container. All the
developer would need to do is specify that events with a specific type
and binding types would be distributed by a certain queue or topic.
(web-beans.xml would be the right place to specify this mapping.)
What I'm thinking is the following:
(1) Event observers may specify that they receive events asynchronously:
void invalidateCache(@Observes @Asynchronously @Created Product
product) { ... }
or even:
void invalidateCache(@Observes(ASYNCHRONOUSLY) @Created Product
product) { ... }
By default, an asynchronous observer is a purely local construct.
However, unlike synchronous observers, an asynchronous observer is
called in a different set of web beans contexts to the contexts in
which the event was fired.
(2) A topic or queue declaration may specify a set of events which are
distributed via that queue/topic:
<Topic>
<destination>java:comp/env/jms/CacheInvalidationEvents</destination>
<connectionFactory>java:comp/env/jms/TopicConnectionFactory</connectionFactory>
<events>
<myapp:Product>
<myapp:Created/>
</myapp:Product>
</events>
</Topic>
This declaration means that any event that is "assignable" to the
specified type and binding types is a distributed event, distributed
by the named JMS topic.
(3) The Web Bean manager would validate that all observers for any
event distributed via JMS are declared to be asynchronous observers,
and throw an exception if there are any synchronous observers for the
event.
(4) We need to think carefully about the concept of an asynchronous
transaction completion event observer. The following combinations are
semantically correct, and need to be supported, even for the distributed
case:
@Observes @Asynchronously @AfterTransactionCompletion
@Observes @Asynchronously @AfterTransactionSuccess
@Observes @Asynchronously @AfterTransactionFailue
However, this combination is not meaningful:
@Observes @Asynchronously @BeforeTransactionCompletion
(5) Finally, since JMS is a transactional medium, we could support a
further setting which writes the event transactionally to the queue/topic.
However, this setting needs to be a global setting for the event type.
Perhaps an @Transactional annotation for the event type?
WDYT?