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:[email protected]]
Sent: Wednesday, February 25, 2009 4:25 PM
To: [email protected]
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 <[email protected]> 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