[whatwg] Semantic detection of stale server state

Hi all,

This is my first post to this list, so if this discussion is best had
elsewhere, please let me know :)

In today's world of servers being implemented as distributed systems, eg
microservices, there are situations where a client may have more up to date
knowledge of a resource than the server it's requesting the resource from
does.  An example would be one where the server employs CQRS - in CQRS you
have a write-side that is updated synchronously, and a read-side that may
be updated asynchronously, and it may take time for updates to be
propagated from the write-side to the read-side.  So, if a client makes a
PUT request on a resource, and the response returns successfully, and then
the client immediately issues a GET request on that same resource, the
returned resource may not yet reflect the result of the PUT request.  This
is not a caching issue that could be solved by adding a no cache pragma
header - the servers read-side representation of the resource has simply
not yet been updated due to the asynchronous nature of the implementation
of the server.

In order to address the problems associated with these scenarios, it would
be useful if the client could, semantically, detect whether a response it
receives to a query is out of date compared to the knowledge that it has.
It perhaps could use date based headers such as Last-Modified, but this
doesn't tend to work so well in a distributed system - it is impossible in
a distributed system for all nodes to agree on the current time, and clock
skew can be a big problem.  Additionally, the prime use case - a client
seeing its own writes immediately - is likely to need much better precision
than what date headers can offer.

Unless there is a more recent spec that I'm not aware of, I can't see
anything in the HTTP spec that addresses this problem. I'm thinking a
mechanism that extends the use of ETags may be useful - in response to a
PUT, POST or DELETE request, a server may send an ETag header, then the
client in a subsequent request may send that ETag in an If-At-Least-Match
or If-Up-To-Date header. I have considered the existing If-Match header,
except that it's not usually a match that you need to assert - a client
would generally be interested in any other updates that have happened since
it did its update, so If-Match probably isn't the right approach, it should
be a precondition that the server can satisfy at least that tag, not
exactly that tag. The ETag, a value opaque to the client, could represent
the version of the entity after the update was performed, and then the
server, when serving the request, could use it to check whether its
read-side view has a representation that matches at least that version of
the entity.  If it's not, then perhaps the server could respond with a 412
response, though whether this should be considered a client error or server
error is up for debate.

There are also some other considerations, such as what if the client makes
a request to get a resource of which the resource it updated is a subset
of, such as a list of resources, as would be done in a UI where you create
a new thing and then return to a view of all the things you've created - is
there a semantic way that an ETag or other tag could be applied to the list
of things resource?  Also, maybe a failure response is not useful, since
this is intended for use on a GET and so proceeding the request is safe,
maybe it's just useful to return the not yet updated resource in the
response, but indicate to the client that it is stale in a header or with a
new 200 or 300 response code.

Does anyone think that this would be a problem that would be interesting to
provide a semantic solution for in HTTP?

Regards,

-- 
*James Roper*
*Software Engineer*

Lightbend <https://www.lightbend.com/> – Build reactive apps!
Twitter: @jroper <https://twitter.com/jroper>

Received on Tuesday, 22 November 2016 11:42:04 UTC