Merge lp:~leonardr/lazr.restful/multi-part-etag into lp:lazr.restful
Status: | Merged |
---|---|
Approved by: | Graham Binns |
Approved revision: | 124 |
Merged at revision: | not available |
Proposed branch: | lp:~leonardr/lazr.restful/multi-part-etag |
Merge into: | lp:lazr.restful |
Diff against target: |
362 lines (+222/-29) 3 files modified
src/lazr/restful/_resource.py (+75/-28) src/lazr/restful/example/base/tests/entry.txt (+146/-0) src/lazr/restful/version.txt (+1/-1) |
To merge this branch: | bzr merge lp:~leonardr/lazr.restful/multi-part-etag |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Graham Binns (community) | code | Approve | |
Review via email: mp+21398@code.launchpad.net |
Description of the change
OK, this branch will hopefully go a long way towards avoiding the 412 errors that results in bugs like bug 336866 and bug 534066. The solution is as described here: https:/
An entry resource's ETag now has two components: a component describing the state of the read-only fields, and a component describing the state of the read-write fields as well as global information like the current code revision. Conditional GET requests still check the entire ETag, but conditional PUT and PATCH requests only check the read-write portion. This way, server-side changes to read-only fields don't cause PATCH requests to fail. A PATCH request should only fail if there's some possibility that _some other user_ made a conflicting change.
So, let's say a bug's Etag is "foo-bar". If you make a GET request with an If-None-Match of "foo-bar", you'll get 304 Not Modified. If you make a PATCH request with an If-Match of "foo-bar" your request will succeed.
Now let's say some behind-the-scenes cron job runs, and the bug's bug_heat changes. Now the bug's ETag is "baz-bar". Only the first part changed, because bug_heat is not writable. Now, if you make a GET request with an If-None-Match of "foo-bar", you'll get 200 Ok and a new representation with the new value of bug_heat. The request condition will fail. But if you make a PATCH request with an If-Match of "foo-bar", the condition will succeed and your PATCH will go through. After your PATCH goes through, the bug's ETag will be "baz-quux", and a PATCH with an If-Match of "foo-bar" or "baz-bar" will fail.
Hopefully the doctests will make it clear how this system works.