Subject: Re: "Timeout" request header to tell server to wait for resource to become available

From: Benjamin Carlyle <[email-masked]>
Date: Thu, 9 Apr 2015 23:39:41 +1000

On 28 March 2015 at 11:46, Martin Thomson <[email-masked]> wrote:
> I believe that what you want is accomplished by RFC 7240:
> Prefer: wait=5
> The units are perhaps suboptimal for your use case (seconds instead of
> milliseconds), but we might be able to make a change to support finer
> grained timing.

I thought I would write in to describe a use case for combining
Prefer:wait with GET requests. I'm not sure if my case is completely
compatible with Brendan's. My main use case for HTTP, SPDY, and soon
h2 is within highly available safety related (not safety-critical)
SCADA systems. Within these systems there is often a requirement for
soft realtime transfer of data, that is delivery of information within
an order of magnitude or two or three of the effectively latency of
the network. The current preferred way to do this with HTTP is to have
a "main" URL for a given collection of data, plus a series of "delta"
URLs. Issuing GET to the main URL returns immediately, and includes a
Link header to the next delta URL. A client will issue GET to the
delta URL which includes an time-like identifier for the recent main
resource representation. The delta response will include a Link header
to the delta.

A crude example:
-> GET /main
<- 200 OK
<- Link: </delta/5>; rel="delta"
<- (current state)
-> GET /delta/5
<- 200 OK
<- Link </delta/7>; rel="next"
<- (changes from t=5 to t=7)

The request to the delta URL is a "long poll" where the client is
willing to wait until content is available at the delta URL it has
been given. There are two main alternatives to a success response for
the delta URL:
4xx - the delta is invalid for some reason, say a circular buffer is
keeping track of recent changes on behalf of all clients and the index
into that buffer that the client holds is no longer valid
204 - the delta is valid but no changes have occurred yet. The server
can validly return 204 at any time to a delta request so can shed
clients it no longer wants to serve etc.

I haven't been using the RFC7240 code but I may start using it when we
deprecate a h2-like internal protocol dating back many years and
switch to official h2. Currently I'm using a custom header sent in the
GET request to indicate how long the client is willing to wait for a
response. Typically this might be around 4s after which the client
will expect a response - otherwise it might be that the server or TCP
connection is dead. In this way the 204 response acts as a heartbeat
message to the client when the change rate is low. I refer to the
technique as long poll delta encoding, and for synchronisation of data
across a network between control system components with
well-controlled failure modes I think it's actually hard to beat -
partially because this particular interaction is stateless. A client
only has to make one request at any time to come back into sync and
the server can drop clients at will without loss of synchronisation
state. A header like this can also be a hint to layers that do not
understand the full request semantics to allocate resources to the
request differently, for example by shifting workload onto different
thread pool.

I wrote about the mechanism back in 2012 in case anyone is interested
in a slightly more complete though slightly out of date treatment of
the subject: http://tools.ietf.org/html/draft-carlyle-sem-delta-encoding-00

Obviously there is a lot more to the story of ensuring good responses
to failure for HTTP requests. As a blanket rule for these systems
there exists a time limit T in the order of a few seconds such that
should any kind of network failure occur clients detect the failure
and reestablish comms to a new server. Doing a long poll with a
timeout is one part of that.

---

From: Martin Thomson <[email-masked]>
Date: Thu, 9 Apr 2015 09:50:28 -0700

That sounds like exactly the case Prefer: wait=x was designed for.

Note that with HTTP/2 you can set the header field to the actual time
that you are willing to wait, and use PING frames to test (and
maintain) connectivity.