tomcat-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Mark Thomas <ma...@apache.org>
Subject Re: async and thread constraint
Date Wed, 11 Feb 2015 13:27:00 GMT
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: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org


Mime
View raw message