[
https://issues.jboss.org/browse/CDI-729?page=com.atlassian.jira.plugin.sy...
]
James Roper commented on CDI-729:
---------------------------------
The problem is that while it is possible for event publishers to fire an event
asynchronously, that is, fire it and then continue processing immediately, and then
asynchronously be notified when the event has been successfully observed by all the
observers, there is no way for event observers to handle the event asynchronously, that
is, they can't trigger some asynchronous IO, then return immediately from the method,
and then asynchronously let the publisher know that they event was handled successfully.
The only thing they can do is block.
So, imagine I wanted to do a REST call using an asynchronous HTTP client, this REST call
is done using the following method:
{code:java}
public CompletionStage<Response> makeRequest(Request request);
{code}
Now, if I implement an observer:
{code:java}
public void handleEvent(@ObservesAsync MyEvent event) {
CompletionStage<Response> response = makeRequest(convertEventToRequest(event));
// Now what do I do?
}
{code}
The problem with the above is that {{handleEvent}} is going to return before the REST
request has been made, and so neither the status, nor backpressure, can be propagated back
to the event publisher, unless of course I block on the {{CompletionStage}}, in which
case, I'm no longer asynchronous. In order to support asynchronous propagation of
backpressure and success signalling, CDI needs to support observer methods that return
{{CompletionStage}} so that the methods can indicate when they are done handling the
event, eg:
{code:java}
public CompletionStage<?> handleEvent(@ObservesAsync MyEvent event) {
CompletionStage<Response> response = makeRequest(convertEventToRequest(event));
return response;
}
{code}
What the impact here is is when I publish the event using the following code:
{code:java}
CompletionStage<?> fireEventResult = event.fireAsync(myEvent);
{code}
The {{fireEventResult}} completion stage won't be redeemed until after the
{{CompletionStage}} returned by {{handleEvent}} is redeemed. This ensures that something
publishing events asynchronously doesn't overwhelm the event handlers, by ensuring
backpressure gets propagated, and also ensures that if there's an error that's
asynchronously encountered, that the publisher can be aware of that.
We're looking at integrating the MicroProfile messaging spec with CDI asynchronous
events, and the ability to propagate backpressure asynchronously through event publishing
is necessary before we can do that, otherwise an incoming message stream from a message
broker could easily overwhelm a server. Our issue for tracking that feature is here:
https://github.com/eclipse/microprofile-reactive/issues/30
Async event not CompletionStage friendly
----------------------------------------
Key: CDI-729
URL:
https://issues.jboss.org/browse/CDI-729
Project: CDI Specification Issues
Issue Type: Feature Request
Reporter: Romain Manni-Bucau
The goal of this ticket is to enable user to get injected the completion future instead
of the raw event and return another completion stage (generic type ignored) to enable the
"chain" to be synched.
Here is a sample:
1. fireAsync(persistEvent)
2. observer implementation does: return future.thenCompose(db::doAsyncPersist)
3. when the user gets back the result of the fireAsync the doAsyncPersist is completed.
--
This message was sent by Atlassian JIRA
(v7.5.0#75005)