-
Notifications
You must be signed in to change notification settings - Fork 381
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Implementing the Cache-Control "must-revalidate" directive #3364
base: master
Are you sure you want to change the base?
Conversation
1e6fb66
to
b33929f
Compare
I added this pull request to #3246 ( 7.0 Compliance improvements) |
5faaddf
to
a34ec5c
Compare
62a8808
to
3ea49a8
Compare
3ea49a8
to
ee40cda
Compare
One thing that should be noted is the risk of serialization introduced by this change, negating the non-zero Cache-Control: public, must-revalidate Such a change should get a fair share of red tape in the release notes and relevant documentation. For this use case we would need a non-zero
This way we could cache resources with no TTL based on the revalidation status (200 or 304). This would however be a major VCL breaking change since a zero TTL is interpreted today as uncacheable. To avoid serialization it would be necessary to wake up anyone in the waiting list regardless of the outcome (200 or 304) to be served with a fresh response. Even a negative TTL shouldn't be interpreted as uncacheable (and more precisely unstorable) if we allow grace and keep. That doesn't change my review, I wanted to mention the risks and where we could go if we dial this compliance knob up to eleven. I had mentioned some of that to @ThijsFeryn prior to his submission but didn't have time to elaborate here last week. |
Request serialization can only happen when you set a zero TTL. Having a zero grace value does not affect this, so its safe. |
This is prevented with the current This is what meant by "risk", we are pulling a rug under existing VCL. And I guess I forgot some thoughts: It can be easy to turn a cacheable response into a hitmiss object because the TTL is negative, especially in a tiered setup where Varnish's backend might be another Varnish instance serving a graced object. Making an object storable based on ttl+grace+keep would make this a non-issue. The Still, it breaks the assumption that a zero or negative TTL can be used to tell the built-in VCL and the core code that a response is uncacheable: varnishtest "cache negative ttl"
server s1 {
rxreq
txresp -hdr {ETag: "123abc"} -body helloworld
rxreq
expect req.http.If-None-Match == {"123abc"}
txresp -status 304 -hdr {ETag: "123abc"}
} -start
varnish v1 -vcl+backend {
sub vcl_backend_response {
set beresp.ttl = -1s;
set beresp.grace = 0s;
set beresp.keep = 2m;
return (deliver);
}
} -start
client c1 -repeat 2 {
txreq
rxresp
expect resp.body == helloworld
} -run Such a scenario would pass with this change in core code: --- i/bin/varnishd/cache/cache_hash.c
+++ w/bin/varnishd/cache/cache_hash.c
@@ -435,7 +435,7 @@ HSH_Lookup(struct req *req, struct objcore **ocp, struct objcore **bocp)
continue;
}
- if (oc->ttl <= 0.)
+ if (oc->ttl + oc->grace + oc->keep <= 0.)
continue;
if (BAN_CheckObject(wrk, oc, req)) { And we'd need something similar in the built-in VCL. That's it for my compliance detour, I hope I clarified my previous comment. I'm also fully aware of my lack of scrutiny, I haven't researched all the problems that this suggestion could introduce, for now I'm putting it on the proverbial table. |
This PR implements
must-revalidate
based on the spec, stating that whenmust-revalidate
is part of theCache-Control
header, no stale data should be served from cache.In terms of Varnish, this means grace is set to zero.
Example header
This is what such a header could look like:
Combining
must-revalidate
andstale-while-revalidate
By putting this if-clause behind the
stale-while-revalidate
check, any occurrence ofmust-revalidate
will supercedestale-while-revalidate
.If for some weird reason, the backend would send back both directives, grace would be set to zero, as illustrated in the example below:
This is probably a breaking change
Because this PR changes the behavior of how grace is set, this could be considered a breaking change.
If you would accept this patch, I'm not sure at what point this would end up in a future release of Varnish.