Hi Tim, Tal,
It seems that we all better see the implications. Regarding the exception idea, this looks similar to Jetty continuations mechanism, which is IMHO working but complex and unintuitive: http://wiki.eclipse.org/Jetty/Feature/Continuations Can we do better/easier? If we step back a little, here is the list of design issues/goals we want to address: · Handling of HTTP transactions including one request, potentially several provisional responses and a final responses · The current Uniform interface strongly implies that there is only one request and one (final) response possible, corresponding to the objects provided as parameters · We want to allow several threads to process the messages of the same transaction in order to: o resume sending after a long request processing o progressively send a response entity (such as Server-Sent Events) o progressively retrieve a large request entity · Consistently behave on both client and server sides · Allow assembly of a processing Restlets chain including routers and filters · Ensure that the default scenario (synchronous processing with one request and one response) stays simple (as simple as today?) · Ensure that server-side request can be proxied on the client-side (using Redirector in outbound mode for example) Looking at all those issues, I (still) think that the cleanest way is to view the Restlet processing chain as a directed and dynamic graph where Restlet instances are nodes processing requests coming in first and then coming back (unless it is a leaf node). In term of pseudo-code, here is what I have in mind for the Restlet class: · [final] handle(Request, Response) : void // capable of sync or async handling, manages processing stack o calls handle(req, resp, true) · [final] handle(Request, Response, boolean incoming) : void o For incoming calls · add the Restlet at the top of the processing stack · invoke handleIn( ) · if a Restlet is returned, invoke handle( ) on it · if the response has been synchronously committed, invoke handleOut( ) o For outgoing calls · if the current Restlet isnt at the top of the processing stack, throw an error · invoke handleOut( ) · remove the Restlet from the top of the processing stack · if the response has been asynchronously committed, invoke handle(req, resp, false) on the Restlet at the top of the stack · [protected] handleIn(Request, Response) : Restlet // handle incoming calls, returning any next Restlet to call o Intended to be overridden · [protected] handleOut(Request, Response) : void // handle calls going out back to the client from further Restlets in the stack o Intended to be overridden Makes sense? :) BTW, Ive updated the related wiki page with those notes: http://wiki.restlet.org/developers/172-restlet/g1/297-restlet.html Best regards, Jerome -- <http://www.restlet.org/> http://www.restlet.org <http://twitter.com/#!/jlouvel> http://twitter.com/#!/jlouvel De : tpeie...@gmail.com [mailto:tpeie...@gmail.com] De la part de Tim Peierls Envoyé : dimanche 25 décembre 2011 14:13 À : discuss@restlet.tigris.org Objet : Re: Re: Re: Re: Status of Asynchronous Support I think we're in violent agreement. I'm just worried about the difficulties of arranging for the afterHandle calls to occur in a different thread. It's a huge change with lots of potential for hard-to-detect bugs. I'm not arguing against doing it. --tim On Sun, Dec 25, 2011 at 12:02 AM, Tal Liron <tal.li...@threecrickets.com> wrote: I would have two answers: 1) Isn't that the price to pay for asynchronicity, and the desire of the user? The whole point is to implicate a different set of threads into communication with the client. Of course, hybrid thread-pool-plus-event-driven servers come to mind, which queue up event responses but handle them on a single thread pool. There are advantages to that, but it didn't seem to be the design goal for Restlet. 2) It could be handled by the application's TaskService. Still, I would imagine that the user would not always want that. How about this: response.commit(token) ...to commit in the current thread, and... response.commitLater(token) ...to commit in the TaskService. > But doesn't that still leave the problem of arranging for all the > afterHandle calls to happen in the thread that does that commit? That's > what scares me. ------------------------------------------------------ http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447 <http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447&dsMessageId=2899 780> &dsMessageId=2899780 ------------------------------------------------------ http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447&dsMessageId=2900556