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? if not I can dump some stacks to make the calls more concrete Romain Manni-Bucau @rmannibucau http://www.tomitribe.com http://rmannibucau.wordpress.com https://github.com/rmannibucau 2015-02-11 10:30 GMT+01:00 Mark Thomas <ma...@apache.org>: > On 11/02/2015 09:21, Romain Manni-Bucau wrote: >> Well it is not different and both should be allowed IMO, i just tried >> to find a solution for the original bug without breaking common >> usages. It should be easy to reproduce with a servlet: GET >> /foo?start=true -> create an async context then GET >> /foo?continuer=true -> resume without popping a new thread. nothing >> will happen. >> >> Well said otherwise: why tomcat is preventing to continue a request in >> a container thread? If this is for an internal reason (issue >> mentionned by Konstantin) then it is a bug. >> >> Point is ATM this feature doesn't work and AFAIK it is not fobidden by the >> spec. >> >> Another point is startAsync works but you reuse container pool (so >> previous issue sounds really like a bug). startAsync works cause the >> context (this marker flag) is generally different (not set) when you >> call it. > > Sorry. I don't follow the point you are trying to make at all. You need > to explain clearly - to folks who have no idea what JAXRS 2 is trying to > do - what the problem is and why (ideally with reference to the Servlet > specification) you think there is a bug in Tomcat. > > Mark > > >> >> >> >> >> Romain Manni-Bucau >> @rmannibucau >> http://www.tomitribe.com >> http://rmannibucau.wordpress.com >> https://github.com/rmannibucau >> >> >> 2015-02-11 10:15 GMT+01:00 Mark Thomas <ma...@apache.org>: >>> On 11/02/2015 07:58, Romain Manni-Bucau wrote: >>>> Well in two words if you take the most common example of JAXRS 2 >>>> continuation (@Suspended) it will do it (doing the link with >>>> servlets): >>>> >>>> -> request 1 -> suspend async context >>>> -> request 2 -> async context dispatch (resume) >>>> >>>> issue is that resume is called from request 2. In other words >>>> ContainerThreadMarker should check current thread id and not just a >>>> boolean cause request 2 is in a container thread but this is not >>>> request 1 thread so you can do request 1 async operations in it. >>>> >>>> wdyt? hope it is clearer >>> >>> Nope. I still don't see what the problem is or why forcing a dispatch to >>> a different container thread is any different to continuing to execute >>> on the current container thread. >>> >>> Mark >>> >>> >>>> >>>> >>>> >>>> Romain Manni-Bucau >>>> @rmannibucau >>>> http://www.tomitribe.com >>>> http://rmannibucau.wordpress.com >>>> https://github.com/rmannibucau >>>> >>>> >>>> 2015-02-11 0:16 GMT+01:00 Mark Thomas <ma...@apache.org>: >>>>> On 10/02/2015 23:06, Konstantin Kolinko wrote: >>>>>> 2015-02-10 14:16 GMT+03:00 Romain Manni-Bucau <rmannibu...@gmail.com>: >>>>>>> Hi guys, >>>>>>> >>>>>>> in org.apache.coyote.AsyncStateMachine#asyncDispatch tomcat checks >>>>>>> ContainerThreadMarker.isContainerThread() >>>>>>> >>>>>>> basically it prevents to use JAXRS 2 @Suspended without creating >>>>>>> custom threads - which is not intended. >>>>>> >>>>>> I do not know what the above is about. >>>>> >>>>> Me neither. >>>>> >>>>>>> Was this limitation intended or just to try to avoid to consume >>>>>>> container threads? >>>>> >>>>> In addition to the reason Konstantin explains below, it is also a >>>>> performance benefit. If we are already on a container thread and need to >>>>> process a dispatch() it is much more efficient to stay on that container >>>>> thread to process the dispatch() than it is to return the current >>>>> container thread to the pool, monkey about with the poller (or >>>>> equivalent for the connector in question) to trigger an event, wait for >>>>> the event to fire and poller to allocate the socket to a container >>>>> thread and then process the dispatch. >>>>> >>>>> Mark >>>>> >>>>> >>>>>> >>>>>> Looking at blame results, those lines were added in >>>>>> http://svn.apache.org/r1594198 >>>>>> "Address root cause of ReadPendingException rather than swallowing it." >>>>>> >>>>>> Discussion that preceded that commit is in "Re:r1593303" thread, >>>>>> http://tomcat.markmail.org/thread/4kwnhzwhhxi43sob >>>>>> >>>>>> <quote> >>>>>> I think I have got to the bottom of this. An async dispatch always >>>>>> adds the socket to the poller but if the dispatch occurs on a >>>>>> container thread then it will also be added to the poller when that >>>>>> thread exits the AbstractConnectionHandler.process() method. >>>>>> >>>>>> This looks like a bug with all the connectors but one that is more >>>>>> obvious with Nio2 because it triggers the ReadPendingException. Fixing >>>>>> this bug highlighted a minor issue on shutdown. I have a fix for that >>>>>> too. Commits to follow shortly. >>>>>> </quote> >>>>>> >>>>>> Best regards, >>>>>> Konstantin Kolinko >>>>>> >>>>>> --------------------------------------------------------------------- >>>>>> 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 >>>>> >>>> >>>> --------------------------------------------------------------------- >>>> 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 >>> >> >> --------------------------------------------------------------------- >> 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 > --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org