Comments (15)
Why shouldn't braid patches be cached? They are cached given the version, no? We should just make ETag == Version.
from braid-spec.
They should only be cached if the proxy understands the Braid protocol.
Imagine a braid-aware client requests a HTML page, and the request goes through a CDN that doesn't support braid. Then the origin server will send a patch, or stream of patches, through the CDN.
But if a non-braid client then requests that page via the CDN, the CDN could respond with a patch instead of the full resource. The non-braid client would then try to display a patch instead of HTML.
I'm not entirely sure that this happens with CDNs, but it seems likely, and mirrors the way the Range Requests spec has been written.
from braid-spec.
Also, as for ETags, they unfortunately do not == Version, because they depend on Content-Encoding, not just the response body. In other words, if the network channel gzips the response body, it'll have a different ETag, even though it's the same Version.
from braid-spec.
Interesting fact about ETags, but not sure if it matters. I am realizing it does not really help with the fact that a new client still gets wrong contents, in your scenario. But I am not so sure if you are right about the scenario:
But if a non-braid client then requests that page via the CDN, the CDN could respond with a patch instead of the full resource. The non-braid client would then try to display a patch instead of HTML.
I do not thin this is possible, because content-type of the patch and non-patch is different.
So if braid-aware client wants a patch at version X, it should issue GET with version header and content type set to some patch format. If it wants state at X, it should issue GET with version header and content type set to the format in which it wants the state (JSON or HTML). And braid-aware server will provide in the list of content types it accepts both the non-patch and patch content types.
And all of those responses can be cached, because they are immutable. The only thing which is not immutable is asking for a resource or a patch without a version (in which case you get the latest state/patch).
So I do not see a problem here?
from braid-spec.
content-type of the patch and non-patch is different
Actually, in the current spec—as in range requests—the Content-Type remains intact when you switch to a patch or a Range Response.
Example (Range Request):
HTTP/1.1 206 Partial Content
Date: Wed, 15 Nov 1995 06:25:24 GMT
Last-Modified: Wed, 15 Nov 1995 04:58:08 GMT
Content-Range: bytes 21010-47021/47022
Content-Length: 26012
Content-Type: image/gif
... 26012 bytes of partial image data ...
Example (current Braid spec):
Request:
GET /animated-braid.gif
Subscribe
Response:
OK 200
Subscribe
Cache-Control: no-cache, patch
Patch-Type: braid(bytes, sync9(array))
Content-Type: image/gif -- Frame 1
Patch-Type: braid(bytes, sync9(array))
Content-Length: 1239
[100:200] = <binary data>
Content-Type: image/gif -- Frame 2
Patch-Type: braid(bytes, sync9(array))
Content-Length: 62638
[348:887] = <binary data>
I remember thinking about this fairly hard before making this design decision, but don't remember OTOH the specific use-cases that requires it. If I thought for a bit they might come back to mind...
In the current spec, the thing that distinguishes a request for patches vs. full content is the presence of any of these headers:
Subscribe
Version
Parents
I'm not sure if existing CDNs would distinguish requests containing these headers, or not, in caching. I bet this is spelled out somewhere in the HTTP specs...
from braid-spec.
Oh, I missed that. That is a different design decision that what I was thinking/expecting, so maybe I skipped over that.
Hm, I would love to understand why you would prefer this. I mean, in my view :
- I can request a content type to get state.
- We have default patch format, braid-patch, we can use for all patches as their content type. The braid-patch might then apply or not apply to given content type based on its parser type.
Those two are different to me.
I'm not sure if existing CDNs would distinguish requests containing these headers, or not, in caching. I bet this is spelled out somewhere in the HTTP specs...
There might be some caching option to tell which headers to use for caching?
from braid-spec.
I'm not sure what you mean by this:
Hm, I would love to understand why you would prefer this. I mean, in my view :
- I can request a content type to get state.
- We have default patch format, braid-patch, we can use for all patches as their content type. The braid-patch might then apply or not apply to given content type based on its parser type.
Those two are different to me.
from braid-spec.
I am continuing the discussion from above. That we should use two different content types for state vs. patch. And that for patch we have a default content type we can use: the braid-patch one. So not sure why to have same content type and have this issue you are describing here?
from braid-spec.
After more investigation here, you are right, when using range-requests you use same content-type as the full content is. And in that case partial content status code should be used to fix the caching problem you are describing.
But when fetching a particular version, you would not be using really range requests. I mean, you can, especially with our new range units, but that would still be just fetching a subset of the state. So GET
+ Version
header + Range
header would return you a subset of the state at given version. That is neat. But that is not the patch which made the previous version into this version.
To that get that patch, I would suggest you issue a request where in Accept
you ask for patch content type. Then you get patch which brought you to that version. That means you could do:
GET
+Accept: text/html
to get HTML contents of the document.GET
+Accept: application/json
to get JSON of the state used to render that document.GET
+Accept: application/json+patch
to get a range patch of how that JSON state came up to be. (I have yet to add+patch
suffix to the PR I just made.)
And there will be no caching issues with all of that.
from braid-spec.
I think we can use Vary header and require Braid HTTP client to always list Version
and Parents
there?
from braid-spec.
I'm not sure how the cache-control solution solves the problem here. Consider: https://tools.ietf.org/html/rfc7234#section-5.2.3
The Cache-Control header field can be extended through the use of one
or more cache-extension tokens, each with an optional value. A cache
MUST ignore unrecognized cache directives.
That means any cache that has no idea the patch
CC exists MUST ignore it. That will allow the proxy to cache the response and return it to an unsuspecting client.
from braid-spec.
@alficles, that's why the proposed Cache-Control header value is Cache-Control: no-cache, patch
.
A cache that doesn't understand patch
, but does understand no-cache
, will only obey the no-cache
part, which is fine.
A cache that does understand patch
will know that it can override the no-cache
directive because it can cache it as a patch.
However, we seem to have moved on to simply using a 209 Subscription
response status code instead. That's what's in the current spec, although it looks like we haven't updated this Github issue yet with the resolution.
from braid-spec.
Ugh. This is why I shouldn't make comments on Friday afternoon. Sorry about that. no-cache, patch
works just fine.
I've got some other concerns about the 209 code, though. Adoption is going to be a real bear, because some proxies have a tendency to block what they don't understand. In any case, I think whatever Connection-oriented solution we find for #62 will greatly inform this decision here.
from braid-spec.
Mmm, interesting point about proxies blocking what they don't understand! Again, I'm glad to have your expertise engaged to point out issues like this.
This sounds like a question we might be able to test empirically. On the one hand, Cache-Control: no-cache
might not be supported globally (since it was introduced at some point after HTTP v0.9 if I recall correctly), and on the other, a 209 response code might be dropped entirely.
Running some tests on a variety of real networks should help us learn what to do about this.
from braid-spec.
Unfortunately, I've found evidence that the status code 209 trick fails to prevent Chrome from caching.
Specifically, I ran into this issue: https://stackoverflow.com/questions/27513994/chrome-stalls-when-making-multiple-requests-to-same-resource
To reproduce this, I did this:
- Sent a GET Subscribe request to a server. Server responds with 209.
- Sent a PUT request to the server.
The PUT request gets delayed by 20 seconds, because Chrome thinks they are operating on the same cache, and locks its cache for 20 seconds.
This issue goes away if you add "Cache-Control no-cache, no-transform". This suggests that some implementations might need the Cache-Control headers after all. We should test other browsers and proxies before making a final call.
from braid-spec.
Related Issues (20)
- Heartbeat messages to prevent timeouts HOT 8
- Subscriptions with no immediate response HOT 2
- Add top level Patch-Type to subscriptions HOT 3
- What error code should we use when historical versions are missing? HOT 1
- Get requests with 'version' header should all appear in same section. HOT 3
- Allow 404s within a Subscription HOT 7
- Cache-Control is missing from the spec HOT 1
- Typo on braid.org HOT 1
- Subscription without payload HOT 6
- Compression or inheritence for headers
- Guidance for PUTs to legacy servers HOT 9
- Articulate the general form of Updates HOT 1
- Subscription parameters HOT 2
- Write Abstract Protocol HOT 3
- Place fields in correct IANA Registry
- Multi-ID versions used in text before they are explained HOT 2
- Difference between ignoring and rejecting an update HOT 3
- Reporting versioning-related errors
- Memento protocol HOT 5
- First-Readthrough Nitpicks HOT 3
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from braid-spec.