Hi Rob, Thanks!
Yeah, your suggestion to use the post/redirect/get pattern is a great way to solve this issue, but it violates my first stated constraint -- a synchronous solution. :) The only reason I want a synchronous solution is for simplicity -- to support lowest common denominator clients such as curl, without requiring the user of the API to write a script with logic such as what you propose below. However, no argument that adding this asynchronous complexity would solve the problem. Also, I forgot to mention that my imaginary resource specifies a POST response body with a “report” of the result of the POST operation (such as a list of status codes or error messages, one for each record in the data set). Given all this, here is another solution I thought of: Modify the implementation of the resource so that it doesn't stream the entire request body from the client to the server as a first step, and then process the data as a second step. Instead, break up the processing into "chunks" by reading N records from the request body and processing only those records, storing the result of processing that chunk in memory, and so on, all within a single transaction. The good news is that this would put a ceiling on the "wait time" from the client's perspective. The bad news is that this would extend the transaction demarcation to include the network -- if the server encounters an extremely slow (say, dial-up) client, it could have the detrimental effect of keeping a data store connection and transaction open for much longer than necessary. (This only matters because the whole operation is transactional.) Anyone else have any thoughts? - Lu From: Rob Heittman [mailto:rob.heitt...@solertium.com] Sent: Wednesday, February 25, 2009 4:25 PM To: discuss@restlet.tigris.org Subject: Re: detecting that client aborted or timed out Hi Lu, As in the reference you cited, I think this is just on the list of things that can't be done with sockets. The only way to find out is to try some I/O and see what's what. One of the risks associated with your approach is that most user agents, unless specially configured, will time out after a long period of no I/O. When the client is done sending its POST, if there is a long wait (multi minute) involved in the persistence operation before any response data is sent, the user agent will typically interpret that as failure. To avoid this, you can poke bytes out a response stream during your persistence operation to keep the client's timeouts from triggering, the writing of which *might* throw an exception if the client goes away. This depends on how much your container hierarchy likes to buffer output and bubble exceptions. I'd really rather not stake my life on this behavior ... even if I got it to work once, I'd be deadly afraid it would quit working the next time a minor change was made in the server environment. Ideally, I'd prefer to do it using something like a post/redirect/get pattern where immediately upon successful completion of the initial POST entity submission, I thread the persistence op, and immediately return a 303 redirect to a status URI that can be polled via GET for information about the status of the persistence operation. This would allow me to return stuff like percentage completion and so forth, and for a live UI or monitoring system to expose this information. But my calling client can still expose it synchronously and treat it as a single op if needed: // do POST operation if(response.getStatus().equals(Status.REDIRECT_SEE_OTHER)) { boolean completed = true; while(!completed) { // do GET operation on response location // interrogate response for completed status or an error condition // wait around with Thread.sleep() or some such } } Else { // handle unexpected status conditions of the initial POST } Maybe some other folks have better ideas ... ! - R On Wed, Feb 25, 2009 at 5:00 PM, Luis Saenz <lsa...@taxcient.com> wrote: > Is there any way for the restlet application (server-side) to detect that > the HTTP request (client-side) has terminated prematurely? (For example, > either due to the client aborting or timing out.) ------------------------------------------------------ http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447&dsMessageId=1229956