Re: No validator in 200 response for conditional update

On 2018-11-06 23:35, Vladimir Lashchev wrote:
> Thanks for your replies!
>
> In general, since the spec says that server "MUST NOT" send an ETag in some case so in order to comply with the spec we must implement that logic and it does not matter if it is a corner case or if it may happen only once in our API. In reality it is actually not an edge case and happens quite often (up to single digit % of all requests in high volume concurrent scenarios).

Are we talking about the same thing?

1) It needs to be a state-modifying request,

2) That comes with a validator,

3) The validator doesn't match, but the current state of the resource does.

So this only happens when multiple clients do concurrent updates of a
resource, and write the same content.

It would be interesting to understand why this happens so frequently -
can you provide more information about the type of the server/service?

> That's why I am trying to understand the reason because that clause calls for a lot of development.
>
> Why "a lot" of development?
> Because the clause "... unless it can verify that the request is a duplicate of an immediately prior change made by the same user agent ..." requires us to persistently track previous requests from all clients which is a huge infra requirement for stateless API server farms (which is a typical design for servers with high performance requirements).
>
> Actually, scenario of that 2xx clause (as I read it) is a bit more complicated - it applies in the case when 2 agents (A1 and A2) are talking to the sever and trying to apply semantically same changes or same agent asks for the same change in non-consecutive requests. Here is my understanding:
> 1) "state change is being requested and the final state is already reflected in the current state" ==> means that requests may not be identical, as long as they ask for the same end-result state.
> 2) "server MUST NOT send a validator header field in the response unless it can verify that the request is a duplicate of an immediately prior change made by the same user agent " ==> means that:
> a) server MUST NOT send ETag to A2 if state change was done by A1, but similar change is requested by A2
> b) server MUST NOT send ETag to A1 if state change was done by A1 but there was some other request (even GET without any side-effects) between that original change request and a new, semantically-identical change request.

In-between GET requests may be covered by "duplicate of an immediately
prior change made by the same user agent" -  but maybe this could be
made more clearer.

> So expanding on Yishuai's example to include all cases it would be something like:
>
> (step 1) A1 --> S : PUT "a" (unconditional)
> (step 2) S --> A1 : 204 No Content, ETag: "a"
> (step 3) A1 --> S : PUT "a", If-Match: "b" (not satisfied)
> (step 4) S --> A1 : 204 No Content, ETag: "a" (same change-originating agent, same end-result requested in the immediate prior request)
> (step 5) A2 --> S : PUT "a", If-Match: "b" (not satisfied)
> (step 6) S --> A1 : 204 No Content (No ETag) (not a change-originating agent, same end-result requested)
> (step 7) A1 --> S : GET ... (unconditional, no side-effects)
> (step 8) S-> A1 (doesn't matter what is replied here)
> (step 9) A1 --> S : PUT "a", If-Match: "b" (not satisfied)
> (step 10) S --> A1 : 204 No Content (No ETag) (same change-originating agent, same end-result requested, but not in the immediate prior request)
> (step 11) A3 --> S : PUT "zzz", If-Match: "b" (not satisfied)
> (step 12) S --> A1 : 412 No Content (No ETag) (any agent, different end-result requested)
>
> My question is about (step 6) and (step 10) where server MUST NOT send a ETag value back.
> Above is quite complicated logic required without explanation and it is not clear of how it is better/safer than simple and stateless:
> (step 1) A1 --> S : PUT "a" (unconditional)
> (step 2) S --> A1 : 204 No Content, ETag: "a"
> (step 3) A1 --> S : PUT "a", If-Match: "b" (not satisfied)
> (step 4) S --> A1 : 204 No Content, ETag: "a" (any agent, same end-result requested)
>   (step 11) A3 --> S : PUT "zzz", If-Match: "b" (not satisfied)
> (step 12) S --> A1 : 412 No Content (No ETag) (any agent, different end-result requested)
> ...

You always have the choice of not replying with 204 but with 412, in
which case the server logic would be simpler, but clients would need to
do more work.

Which brings me back to my question about what kind of server this is
that shows this type of traffic pattern.

Best regards, Julian

Received on Wednesday, 7 November 2018 07:52:13 UTC