On Aug 9, 2012, at 2:49 PM, Bill Burke wrote:
>
>
> 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!
>>
>
> 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.
I guess this depends a lot on the container's architecture. Sometimes, there's a max number of request threads configured in the container and you don't want to tie up one of those on a long running operation to avoid a denial of service.
> 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.
Actually, this is something that we should probably add if we decide to go with this feature.
> 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 ....
> }
What would happen to the associated connection after the resume() in this case? And why would you want to use a web container thread for something like this?
-- Santiago
>
>
>> 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