-
-
Notifications
You must be signed in to change notification settings - Fork 9.6k
Stale cache is served forever if exception and no max age #24248
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
I can confirm this bug. When exception is thrown, using CacheKernel, no max-age then cache is used instead of display error page. |
So you're...
The next request revalidates the cached response. This time, the backend gives an error, status code 500 probably. We'd need to check if the condition
is really the right thing here, but anyway, as long as the first (cached) response has been sitting in the cache for less than the configured I do understand that this can be surprising to annoying during development, but right now I have no clever idea if or how this could or should be fixed in the core. |
I may be overlooking something, but |
…ernel.debug = true (mpdude) This PR was merged into the 3.4 branch. Discussion ---------- Avoid `stale-if-error` in FrameworkBundle's HttpCache if kernel.debug = true | Q | A | ------------- | --- | Branch? | 3.4 | Bug fix? | yes | New feature? | no | Deprecations? | no | Tickets | Fix #24248 (maybe?) | License | MIT | Doc PR | When working with the `HttpCache` in development, error messages may not become visible if a `public` response has been successfully generated for the same URL before. This is because the `HttpCache` from the `HttpKernel` component by default sets `stale_if_error` to 60 seconds. At least when using the `HttpCache` subclass from the `FrameworkBundle`, we know about the `kernel.debug` setting and its intention to support local development. In that case, we could set the *default* `stale-if-error` value to 0. Commits ------- 3a23ec8 Avoid stale-if-error if kernel.debug = true, because it hides errors
See #35305 for additional fixes and tests. |
This PR was squashed before being merged into the 3.4 branch (closes #35305). Discussion ---------- [HttpKernel] Fix stale-if-error behavior, add tests | Q | A | ------------- | --- | Branch? | 3.4 | Bug fix? | yes | New feature? | no | Deprecations? | no | Tickets | #24248 | License | MIT | Doc PR | This PR adds the first tests for `stale-if-error` logic in `HttpCache`. It also fixes an observation from #24248: For responses that have been cached as `public` with an `ETag` but without a lifetime, in case of an error the stale response will be served forever (= as long as the error persists), even beyond the configured `stale-if-error` grace period. Furthermore, it tries to improve compliance with RFC 7234: Stale responses must not be sent (under no condition) if one of * `no-cache` * `must-revalidate` * `proxy-revalidate` or * `s-maxage` (sic) is present. This can be found in the corresponding chapters of Section 5.2.2 for these directives, but is also summarized in [Section 4.2.4](https://tools.ietf.org/html/rfc7234#section-4.2.4) as > A cache MUST NOT generate a stale response if it is prohibited by an explicit in-protocol directive (e.g., by a "no-store" or "no-cache" cache directive, a "must-revalidate" cache-response-directive, or an applicable "s-maxage" or "proxy-revalidate" cache-response-directive; see Section 5.2.2). Because disabling of `stale-if-error` for `s-maxage` responses probably has a big impact on the usefulness of that feature in practice, it has to be enabled explicitly with a new config setting `strict_smaxage` (defaulting to `false`). Commits ------- ad5f427 [HttpKernel] Fix stale-if-error behavior, add tests
Uh oh!
There was an error while loading. Please reload this page.
We have unexpected behaviour which frequently occurs when developing locally where if an exception is introduced into a Twig page, a (previously valid) stale version of the twig page is served. This is because the Symfony cache implements
stale-if-error
, which is implemented here:symfony/src/Symfony/Component/HttpKernel/HttpCache/HttpCache.php
Lines 466 to 481 in 776b964
My understanding of this, particularly line 476, is that stale content will only be served if the ttl of the previously served content is less than 60 (which is the default, as per the below):
symfony/src/Symfony/Component/HttpKernel/HttpCache/HttpCache.php
Line 94 in 776b964
The problem appears to be that we're not setting a max age (our intention is that the decision as to whether something is up to date or not is purely ETag based) and so the ttl is always null.
According to the RFC (https://tools.ietf.org/html/rfc5861#page-3):
As
abs(null) < 60
, line 476 will always be true, this means we will always serve stale content if an exception occurs.Is this the correct behaviour?
I've implemented a test below which help to illustrate what I'd expect the behaviour to be as I understand it regarding the
abs(null)
and normal behaviour ifmax-age
is defined - I couldn't see any obvious tests that exercise this currently and I'm happy to open a PR if they're useful.The text was updated successfully, but these errors were encountered: