It's kind of getting too far in CXF's core for me.
At least I understand what you said bout re-dispatching the message,
sorry for disagreeing before...

---------
Short version of what i think now :
When "resume-suspend", the request re-goes through doGet and when
calling startAsync a new AsyncContext is created.
We HAVE to keep the same Servlet3Continuation object because the
AsyncResponseImpl has a reference to it.
I think that the best way to keep the same Servlet3Continuation
(AsyncListener) is by using the onStartAsync event (that's what it's
made for).

So we might "just" need to know this request is "special" and call
startAsync on it. The onStartAsync would handle the "switch" from the
older context to the newer one.

However : i don't know of to make the internal mechanics of CXF behave
properly... and if I'm right.
---------
Log version with some code :

I played with simple async servlet 3 and understood how to re-pause a message.
You have to dispatch() it, so that it's dispatched a second time,
exactly the sameway. However, you have to know that it's not the first
time you receive it so that you handle it in a different way.

Here is what i began to do :

I think we have to use the startAsync() method of the AsyncListener.
It's made so that you can re-register the same listener to the new
AsyncContext whete startAsync is called a second time on a request.

        @Override
        public void onStartAsync(AsyncEvent event) throws IOException {
            System.out.println("onStartAsync");
            // a new startAsync happened (request was dispatched again)
            // but request was not resumed (isPending), so we assume it's
            // still paused
            if (isPending) {
                // re-register ourselve so that AsyncResponseImpl's reference
                // to this continuation is still valid
                event.getAsyncContext().addListener(this);

                // copy the old context's timout to the new context
                event.getAsyncContext().setTimeout(context.getTimeout());

                // now replace old context reference by the new one
                context = event.getAsyncContext();
            }
        }

I think it's necessary to keep the same Continuation object (the same
AsyncListener) so that the AsyncResponseImpl's reference to the
Continuation object stay valid (for the resume / suspend actions ...).
And the onStartAsync is probably the only way to do it.

So, I also modified the constructor of the Servlet3Continuation so
that it just calls startAsync when beeing created (should trigger the
onStartAsync of the old Servlet3Continuation, and thus making it valid
again because it will register itself against the new AsyncContext).

            if (isNew) {
                // untouched code
            } else {
                req.startAsync(req, resp);
            }

Problems :
 - This newly created Servlet3Continuation is now useless (memory
leak.. invalid reference inside of CXF ?)
 - I tried this but i get a NPE in the PhaseInterceptorChain, probably
linked to the "State" of the message... I don't know about the details
...

I hope this helps you more than the previous messages.

Reply via email to