-
-
Notifications
You must be signed in to change notification settings - Fork 9.6k
[RFC][HttpKernel] Make downstream HTTP caches expire on deployments #31007
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
Comments
There are three parameters that could help achieve this: Would that be enough? |
Great, wasn’t aware of them. So that would be solved out of the box. The remaining question then is: Should the HttpKernel take control of Last-Modified information in this way, possibly overriding the value set in controllers? What about ETag-based validation? |
Expiring the ETag-based validation would involve modifying the Etag generated by the controller, to include some info related to the build in it, alongside the original value. But if your Etag is based on a hash of the content, this might not be needed. Note that using an event listener might be easier to maintain than doing that directly in the kernel |
@mpdude those parameters weren't documented, so we're adding some docs form them in symfony/symfony-docs#11361 |
Now that I see what they were added for, I am not so sure anymore we can use them for this purpose: Imagine events happen in this order:
So the deployment timestamp must be the actual deployment time, not the container build timestamp. However, that’s just a small side aspect that we will be able to solve. Regarding @stof, you’re right with event listeners. Maybe they would need very high and/or low priorities, but that should work. Regarding ETags, they're opaque identifiers and I am not sure I would mess around with them. But that also means the issue would not be addressed if you are used ETag-based validation. |
If the application is the same (ie built_time), then can't you suppose the cached items are the same also, within the boundaries of their own expiration dates? |
Yes, you can (I would). The edge case is if you build the new version, but then serve a response with the old one and have a Last-Modified after the build time. If you deploy only then, the code above would not change anything. (My assumption is that DI container build and cache warming happen on a CI and go into a Docker image, which is deployed sometime later. This might be totally wrong.) |
anything to do in core? shall we close? |
I have heard no objections so far, which I would like to interpret as that you would not reject such a PR as being inappropriate (out of scope for the core). We could do this with event subscribers, thus keeping the Kernel simple. I think I could also make this work for ETags. And the whole thing (fix) could be activated with a Ping @aschempp and @Toflar since I know you guys have dealt with the HttpKernel and caching a lot. So maybe you have an opinion on this as well. Otherwise, feel free to close and I'll follow up with a PR. |
Reading this issue, I'm not this belongs to core. I can see why it could be useful, but this is somewhat opinionated and it would make for a great bundle. |
Ok, I can understand that – closing for now. |
I've quickly discussed this with @aschempp and to be honest, I don't think this is something for core either. Caching is such a complex topic and I don't think there's a one-size-fits-all solution here. |
agreed with toflar. sounds like something that could fit well into FOSHttpCacheBundle (FOSHttpCache is not about symfony listeners but about proxy clients - but as you say, purging downstream caches is painful and/or impossible). basically like cache busting with an asset cache, but for if-none-match / if-modified-since... would be interesting to discuss further in FOSHttpCacheBundle. |
Uh oh!
There was an error while loading. Please reload this page.
In several projects, we are using Content Delivery Networks in front of Symfony applications. In those cases, most of the controllers are able to send
Last-Modified
headers along with the responses. Often this is derived from some database information, for example the time a record has last been saved. Also, there is some infrastructure (bundles, annotations) in place to make validation viaIf-Modified-Since
easy.But there is one case where we've struggled a few times already: When we deploy a new version of the application, there's nothing that makes sure that "old" responses are no longer served from downstream caches.
I am not talking about a "grace" period where the
s-maxage
runs down, but the fact that the downstream cache can successfully re-validate the stale cache entry since my application is not aware of the new deployment (it just looks at the database records). Of course, I do not want to have to deal with deployment timestamps in the controllers either.One solution would be to force a cache purge. But that's an annoying task and can be quite slow in CDNs.
So, one idea I came up with was to add something along the following lines in our
AppKernel
:This checks if there is a
project.deployment_ts
parameter in the DIC which is a unix timestamp. Somehow your deployment tooling has to set or provide this parameter, but that's probably not an issue.The code will then make sure that
If-Modified-Since
conditional requests will return complete200
responses if the given time is before the current deployment. Also, it will update theLast-Modified
header to at least this time.I'd love to get feedback on the issue. Have you encountered a similar problem as well? If there is enough support and interest, I would see how this could be fit into the Kernel or the HttpKernel component.
Update
Just realized that this has nothing to do with the CDN. It affects any validation-based downstream cache, including browser caches that cannot be
PURGE
d at all.The text was updated successfully, but these errors were encountered: