[cdi-dev] [JBoss JIRA] (CDI-729) Async event not CompletionStage friendly

James Roper (JIRA) issues at jboss.org
Tue Jun 19 10:36:02 EDT 2018


    [ https://issues.jboss.org/browse/CDI-729?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=13593930#comment-13593930 ] 

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)


More information about the cdi-dev mailing list