John Bellassai created CXF-7575:
-----------------------------------

             Summary: @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


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
(v6.4.14#64029)

Reply via email to