tomcat-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Romain Manni-Bucau <>
Subject Re: async and thread constraint
Date Wed, 11 Feb 2015 13:54:11 GMT
that's it I think

If you want servlet code let's do it (wanted to avoid code in mail
since I never manage to format it well):

1) request 1 (start the async context) does:

// field context has type AsyncContext
context = req.startAsync(req, resp);
context.addListener(this); // not important for us but it is mainly to
handle errors etc

2) request 2 does in its thread:

// i skip some jaxrs impl internals like getting the response to push
to the client for request 1 etc

And that's all in term of servlet API then you go back in servlet
chain and end on JAXRS servlet (or filter) which identified this
dispatch as a continuation and returns the expected data instead of
doing again request 1 call.

In term of tomcat calls we end up in
java.lang.String) and then

Finally we are in
org.apache.coyote.http11.AbstractHttp11Processor#action which does

if (asyncStateMachine.asyncDispatch()) {
    endpoint.processSocket(this.socketWrapper, SocketStatus.OPEN_READ, true);

and org.apache.coyote.AsyncStateMachine#asyncDispatch checks
ContainerThreadMarker.isContainerThread() which is obviously true
since request 2 is a normal request so dispatch is skipped and
response is never sent (well not as expected and we get a timeout).

Romain Manni-Bucau

2015-02-11 14:27 GMT+01:00 Mark Thomas <>:
> On 11/02/2015 09:35, Romain Manni-Bucau wrote:
>> Ok, let's look a jaxrs 2 sample and bind underlying implementation:
>>     @Path("touch")
>>     @ApplicationScoped
>>     public class Endpoint {
>>         private volatile AsyncResponse current;
>>         @GET
>>         public void async(@Suspended final AsyncResponse response) {
>>             if (current == null) {
>>                 current = response;
>>             } else {
>>                 throw new IllegalStateException("we shouldnt go here
>> back since");
>>             }
>>         }
>>         @POST
>>         @Path("answer")
>>         public void async(final String response) {
>>             current.resume(response /* response content */); // spec
>> doesnt mandate a new thread here but tomcat does
>>         }
>>     }
>> So we have 2 methods:
>> 1) GET: this initiate a request. JAXRS implementation uses servlet
>> container to get an AsyncContext no more
>> 2) POST: the JAXRS AsyncResponse#resume method will just call servlet
>> AsyncContext#dispatch
>> Issue is:dispatch is called in the ThreadLocal environment/context of
>> POST request so resume/dispatch inherit from it. Finally when you go
>> to the async dispatch in Coyoterequest you have a marker bound in
>> ContainerThreadMarker (the POST one) so resume/dispatch is ignored but
>> actually it should work.
>> Is it clearer?
> Not really for me. The description is assuming a familiarity with JAXRS2
> that I don't have. Reading between the lines of what you have written I
> think I have found a problem but I am not sure it is the problem you are
> trying to describe.
> Consider the following which is described purely in terms of Servlet async:
> The first HTTP request (Req1) calls startAsync which creates the
> AsyncContext (AC1), stashes AC1 somewhere and then returns.
> The client then waits for the response (Res1).
> Some time later (but before the AsyncContext and client read timeout) a
> new HTTP request (Req2) retrieves the AsyncContext and calls dispatch().
> This dispatch() *always* needs to be on a new container thread because
> the current container thread is processing Req2/Res2 and the dispatch is
> for Req1/Res1.
> The bug is the test introduced in r1594198 is that the dispatch() was
> processed in the context of Req2/Res2.
> Note in all of the above I am ignoring how/where the AsyncContext is
> stashed and retrieved.
> I think I can put together a test case for the above. If this is the
> problem you are seeing then the patch should be fairly easy. The part
> that will take the time is reviewing the other Async states affected by
> r1594198 to determine if the same problem might occur for any of them.
> Mark
> ---------------------------------------------------------------------
> To unsubscribe, e-mail:
> For additional commands, e-mail:

To unsubscribe, e-mail:
For additional commands, e-mail:

View raw message