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

Reply via email to