I meant "probably nothing you haven't already tested" ... (too much negations in that one).
2012/11/14 Sergey Beryozkin <[email protected]>: > On 14/11/12 13:45, Gege wrote: >> >> Great ! >> >> I'll try it out a bit this evening. But probably nothing you already >> tested. I'm still at experimenting on the features i'll need; i don't >> have a "complete" application yet. >> >> Anyway, thanks for the fix ! Let's make those useful async features usable >> :-) > > > Sounds good :-) > > Sergey > > >> >> 2012/11/14 Sergey Beryozkin<[email protected]>: >>> >>> Hi >>> >>> On 13/11/12 22:24, Gege wrote: >>>> >>>> >>>> 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... >>>> >>> no problems and thanks for spending the time on it >>> >>> >>>> --------- >>>> 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. >>> >>> >>> >>> It does. Believe it or not but I've got my Servlet3 tests working now, >>> after >>> making the changes (based on your feedback): >>> >>> http://svn.apache.org/viewvc?rev=1409193&view=rev >>> >>> It does appear that "req.startAsync()" is really what is needed to get >>> the >>> same context (debugger shows it is actually the same reference that is >>> returned) prepared again, the code does "context = req.startAsync();" >>> just >>> in case, but looks like the same ref is supposed to be returned anyway, >>> given that req.startAsync() operates on the earlier provided servlet >>> request/response objects. >>> >>> Also, setting a listener after 'req.startAsync()' does not seem to make >>> any >>> difference, timeouts are observed and then re-dispatches occur with or >>> without this registration, so it looks like registering a listener is >>> only >>> required during the initial context initialization in the constructor. >>> >>> Can you please experiment with this code in Tomcat ? System tests rely on >>> Jetty Servlet3 async context implementation. >>> >>> Dan, others, please review the above change and let me know if you have >>> any >>> concerns >>> >>> Thanks, Sergey >>> >>> >>> >>> >>> > >
