[ https://issues.apache.org/jira/browse/CXF-7575?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=16344127#comment-16344127 ]
Sergey Beryozkin commented on CXF-7575: --------------------------------------- Hi John, Thanks, the only difference between what I was trying to do and your patch is that in your patch a client has a sync timeout set, I'll try again, but note the tests are using Jetty... Re the possible explanation, I'm still not seeing how that would cause a fault. Lets go step by step. 1) The original request thread has called the service method and added a Runnable 2) The original request thread is now calling AsyncResponseImpl.suspendContinuationIfNeeded 3) In meantime the app thread has run Runnable which called AsyncResponseImpl.resume and set 'resumedByApplication' to true and now is checking 'isInitialSuspend'... 4) At the same time, AsyncResponseImpl.suspendContinuationIfNeeded is called and the first flag which is checked is 'resumedByApplication' Now if, as part of 3), the app thread has set resumedByApplication first to true, then in 4) the request thread will just return and JAXRSInvoker will return the response But if as part of 3) the request thread saw resumedByApplication being still false, then it would assume the continuation would have to be suspended while the app thread, as part of 4), would fail to resume it because the 3) thread has set isInitialSuspend to false in time for the 4) thread to act ... Something like that ? I guess adding a sync would be the simplest option, but that would likely lead to CXF-7037 ? > @Suspended race condition > ------------------------- > > Key: CXF-7575 > URL: https://issues.apache.org/jira/browse/CXF-7575 > Project: CXF > Issue Type: Bug > Components: JAX-RS > Affects Versions: 3.1.14 > Reporter: John Bellassai > Priority: Major > Attachments: CXF-7575.patch > > > There appears to be a race condition with the use of AsyncResponseImpl where > my user thread can invoke resume() before initialSuspend is set to false by > suspendContinuationIfNeeded() and therefore the resume() call does not > actually resume the Continuation _and returns true_, indicating that the > resume was successful even though it wasn't. > I've spent all day trying to make sense of this problem and my understanding > of how all of this works together is still a bit spotty, but it seems to me > that AsyncResponseImpl.suspendContinuationIfNeeded() (or something similar) > should be called _before_ invoking the JAXRS method. Right now, that method > is only called after the JAXRS method is invoked by JAXRSInvoker so the > instance of AsyncResponse passed into the JAXRS method appears to not > actually get suspended (or perhaps _marked_ internally as suspended) until > after the JAXRS method returns. If my async task happens to get finished > very quickly and calls resume() before that happens, it fails silently. > I seem to be able to circumvent this problem by running the following at the > start of my JAXRS method (pseudo code): > {code} > @POST > @Path(....) > void myJaxrsMethod(@Suspended AsyncResponse asyncResponse, ...) { > if(asyncResponse instanceof AsyncResponseImpl) { > ((AsyncResponseImpl)asyncResponse).suspendContinuationIfNeeded() > } > Runnable asyncTask = createAsyncTask(asyncResponse) > submitAsyncTask(asyncTask) > } > {code} > which is why I suspect suspendContinuationIfNeeded() should be called before > JAXRSInvoker invokes the JAXRS method. > One of the things that made this really difficult to track down was that > AsyncResponseImpl.resume() returns true even if the Continuation was not > resumed! If you make it into doResumeFinal(), like was happening in my case, > the return is always true even if cont.resume() is not called. So from user > code, it looks like everything is ok, but the response never gets sent to the > client. > This seems somewhat related to the problems reported in CXF-7037 -- This message was sent by Atlassian JIRA (v7.6.3#76005)