jsr339-experts@jax-rs-spec.java.net

[jsr339-experts] Remove _at_ManagedAsync Re: Re: [jax-rs-spec users] Re: Latest async API changes

From: Bill Burke <bburke_at_redhat.com>
Date: Thu, 09 Aug 2012 14:49:42 -0400

On 8/9/2012 12:06 PM, Marek Potociar wrote:
>> On 8/8/2012 3:06 PM, Bill Burke wrote:
>>> I don't agree with @ManagedAsync. A method annotated with @ManagedAsync
>>> is executed in a separate thread? The servlet container is *already*
>>> doing this so I don't see the point of this annotation.
>
> Apart from the fact that JAX-RS is not bound to run just on a servlet container, I believe you're also wrong when it comes to the assumption that a servlet is executed on a separate thread from the one that received the client connection. Servlet is (or at least can be) executed by exactly the same thread that received the client connection. (Because unless your servlet is async-dispatched, the client connection will close once the call to the servlet method terminates. IOW, async Servlet dispatching is not about async execution, it is about telling the Servlet container that it should not automatically close the client connection when the servlet call returns.) As you know the pool of these connection-handling threads is typically limited. And even if the servlet container had a special servlet execution thread pool, that pool would also be typically limited. Look at any async Servlet example - the request is either dispatched to a different servlet (with a possible speci!
 al threa
dpool), which is however not that useful for JAX-RS resources, or a separate processing thread is manually started in the example.
>

The performance benefit of @ManagedAsync is questionable because most
production quality servlet containers know how to manage lots of
concurrent connections very well. In fact, in most cases, using a
completely separate thread to just marshall and send back the response
on the wire would be detrimental to performance as it would involve
context switching. Also, since you're not providing any way to plug in
an executor you're leaving *A LOT* up to the vendor implementation to
provide configuration.

Now, what *is* interesting is being able to immediately send a response
back to the client and afterwards do some more work. I believe this is
already possible in the current API:

@POST
void doit(@Suspended AsyncResponse res) {
     res.resume(Response.status(202).build()); // response code sent
back to client immediately

     // .... do a bunch of work ....
}



> In JAX-RS the suspended AsyncResponse tells the underlying container (such as Servlet) to not close the client connection (but suspend it instead) when the request processing returns on the primary execution thread. The @ManagedAsync addresses the same task as EJB @Asynchronous does - but for non-EJB resources: It guarantees that the resource method is called on a separate dedicated thread-pool that is managed by the JAX-RS runtime (the actual thread-pool configuration, management and provisioning is not defined by the spec).
>

Comparing @ManagedAsync to EJB's @Asynchronous is comparing apples to
oranges. They are completely different animals. @Asynchronous on a EJB
void method() is a fire-and-forget operation. Fire-and-forget does not
exist in HTTP, unless you want JAX-RS to immediately return a 202
Accepted response and execute the JAX-RS resource method in the
background. Now, that is something I'd be willing to standardize as its
a feature we have in resteasy.

In the other case EJB's @Asynchronous is used with a Future. Since
EJB's use client proxies this is useful and possible. We don't have
that luxury with JAX-RS.


*CONCLUSION*

- Ditch @ManagedAsync
- Add a @FireAndForget or @Accepted annotation that allows for fire and
forget with a 202 Accepted returned to the client:

@POST
@Accepted
public void update(MyData data) {
    ... do stuff ...
}

is equivalent to:

@POST
void update(@Suspended AsyncResponse res, MyData) {
     res.resume(Response.status(202).build()); // response code sent
back to client immediately

     // .... do a bunch of work ....
}


-- 
Bill Burke
JBoss, a division of Red Hat