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 context.setTimeout(valueFromAnywhere); 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 context.dispatch(); 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 org.apache.catalina.core.AsyncContextImpl#dispatch(javax.servlet.ServletContext, java.lang.String) and then this.request.getCoyoteRequest().action(ActionCode.ASYNC_DISPATCH, null);. 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 @rmannibucau http://www.tomitribe.com http://rmannibucau.wordpress.com https://github.com/rmannibucau 2015-02-11 14:27 GMT+01:00 Mark Thomas <ma...@apache.org>: > 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-unsubscr...@tomcat.apache.org > For additional commands, e-mail: dev-h...@tomcat.apache.org > --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org