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

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

From: Santiago Pericas-Geertsen <Santiago.PericasGeertsen_at_oracle.com>
Date: Fri, 10 Aug 2012 11:43:08 -0400

On Aug 10, 2012, at 11:14 AM, Bill Burke wrote:
> On 8/9/2012 5:55 PM, Santiago Pericas-Geertsen wrote:
>>
>> 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 spe!
> ci!
>>>>
>>>
>>> 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.
>>
>
> I really don't think there is any gain by doing this. It's still a thread per connection to matter how you look at it. While you're not consuming a thread of the servlet container, you're consuming a thread of some other executor. You are just not doing anything new that the servlet container isn't already doing for you!

 Does your servlet container use an unbounded thread pool? If so, there won't be much difference. However, most servlet containers use a bounded thread pool. If that bound is reached and the CPU utilization is not maxed out, then using other threads will increase throughput as more connections will be accepted.

>
>>> 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.
>>
>
> IMO, this is a really bad idea. Async HTTP is already an edge case

 Async HTTP is basis for implementing HTML5's SSE protocol, and that is quite useful actually.

> , @ManagedAsync is even edgier than Async HTTP and I have very large doubts its actually useful. Application servers already have a means to manage servlet threads and connections, why are we adding yet another layer to do tje same exact thing? I just can't support this feature...

 We can already do this using an EJB resource class and @Asynchronous. I think the proposal was to support this for the non-EJB case. I would agree that is not a strong requirement for JAX-RS async, though.

-- Santiago

>>> 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?
>>
>
> The connection would be handed back to the servlet container/socket layer after the 202 response is sent back to the client. Just like any other resume() call.
>
> Why would you want to use a web container thread for this use case? Well, why not? It sure is simpler, plus you don't have to worry about propagating things like the security context, transaction context, or any other piece of contextual information that is stored in a thread local.
>
> What this basically allows you to do is fire-and-forget. I'm not saying we should definitely add a fire-and-forget feature. But, I very against the whole @ManagedAsync concept.
>
> --
> Bill Burke
> JBoss, a division of Red Hat