Re: No validator in 200 response for conditional update

On 30/11/18 12:33 pm, Vladimir Lashchev wrote:
>> From: Amos Jeffries
>> Sent: Tuesday, November 13, 2018 9:35 PM
>>> Actually 412 is a proper error as I see it.
>>> Server denies modification request and indicates that request was not
>>> successfully processed (desired resulting state was not achieved).
>>
>> You are assuming "state" here. Which is wrong and leading you to a wrong
>> conclusion.
>> 412 states that the _preconditions_ in that individual request were not
>> obtainable. By itself it does not say anything about any state beyond the
>> individual request message being responded to.
>> The ETag validator is the only bit involving any higher-level state and that has a
>> defined meaning agnostic of the status code.
> 
> I mean "state" as in the paragraph in question (rfc7232#section-3.1):
> "... a) the 412 (Precondition Failed) status code
>    or b) one of the 2xx (Successful) status codes if the origin server
>    has verified that a state change is being requested and the final
>    state is already reflected in the current state of the target
>    resource ..."

The "state" being mentioned in the spec is the exact octets of the
resource itself. The value / octets which the request is attempting to
change.

The way you have been using "state" was to mean the entire history
information of the resource. Which is very a different type of "state".

The difference between changing a document, and changing the changelog
of a document. The former can be done with some flexibility in the
response payload, the latter cannot.




> 
>>> I don't see a scenario where client can treat it as a success. It is a failed update
>>> in an optimistic concurrency flow.
>>
>> When the precondition fails because the Etag has already been changed to
>> a) the desired one, or b) something even newer than the desired one.
> 
> Case a) is explicitly covered with 2xx return code in rfc7232#section-3.1 in question
> Not sure about case b) because ETag in general cannot be compared with "newer", it is _typically_ a black box like hash or GUID.
> 
>> The exact edge-edge-case under discussion here is one situation where the
>> desired state *was* achieved without the preconditions being true.
>> It just happened to be achieved previously by an earlier change request.
> 
> Yes.
> 
> To be precise - it applies only if desired state was achieved by immediate previous request from the same exact agent.
> It actually doesn't matter if it is edge case or not - server that conforms with RFC MUST implement it (that what RFC says).
> 
>>> Anyway, my question is actually about 2xx response and not 412 :-)
>> And the answer perhaps is "why 2xx when 412 conveys the desired meaning".
> 
> Responding with 2xx provides an optimization by converting some error flows into positive flows.
> 
>>> Request #2 can come to any server in the farm and spec calls that all servers
>> should know about previous request from that agent so they can decide whether
>> to send ETag back or not.
>>> It calls for state sharing among all the servers and thus they become not
>> stateless (which we do not want to have).
>>
>> That is not my interpretation.
>> The spec is written in terms of individual request-response transactions. Not in
>> terms of client-service transactions - which may span multiple request-response
>> transactions in a stateful way.
> 
> Could you please help me understand how this sentence from RFC can be applied to a single request-response:
> "unless [server] can verify that the request is a duplicate of an immediately prior change
>    made by the same user agent"
> To apply such logic IMHO server needs to remember prior changes made by each agent.
> And remembering prior changes implies state management on the server farm.

It does require the "immediately prior" state be remembered. Not the
entire history of state, nor state from other servers.

The resource may be sensitive to distributed changes. But that is a
separate issue imposed by the nature of the resource not this RFC. Any
other protocol would face the same issue.


> 
>> The spec / API contract outlines the set of valid responses to any given request.
>> The meanings for various parts of the message is relative to the status and the
>> request type.
>> The spec does *not* dictate statefulness between servers which would lead to
>> identical behaviour.
> 
> Are we still talking about rfc7232#section-3.1?
> How the check required by that section can be achieved without statefulness on the server?

The resource gets saved to a file (or equivalent). Changes to it get
labeled with modification time and some label to identify the client
doing the modification. That is all that is needed IMO to meet the spec
requirement.

The server receiving an conditional change request checks it against
those two details - according to the section-3.1 criteria.

Then (always) updates its stored label and mtime values so any followup
request gets based on the new details. Some nil value for the client
label on duplicates so these repeats get detected easily as a mismatch
on the repeats not "immediately prior".

The server can then respond correctly correctly to any clients while it
asynchronously handles any sync with a master copy.


> 
>> Such as by using the spec interpretation roughly along the lines I used earlier to
>> guide design decisions in the client software:
>>  ...
>> If you try to go beyond that to push multiple meaning into the 2xx status is when
>> you hit problems with whether ETag is possible to send at all, or what value to
>> send when the server is *more* up to date than the client.
>>  Both semantically have the same "I could not do this because I have object "a"'
>> meaning. The client is the agent which knows best whether that situation
>> ignorable or needs handling.
> 
> Going back to the question at hand - what would be your proposal on how to change rfc7232#section-3.1, part with 412 and 2xx + (conditional) ETag responses?
> 
> Mine was to remove this sentence:
> " In the latter case, the origin 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"
> 

Unless someone else can recall why the text is the way it is now. My
preference would also be to go with an Eratta for making that change.

Amos

Received on Friday, 30 November 2018 11:58:10 UTC