Support for Drupal 7 is ending on 5 January 2025—it’s time to migrate to Drupal 10! Learn about the many benefits of Drupal 10 and find migration tools in our resource center.
Problem/Motivation
Currently the redirect is cached with the max-age of whatever variation we have active at the creation of the redirect. I.e.: the last one wins
.
This is wrong as that can well play cache ping-pong and is not a deterministic outcome.
(See #3 and #4 for a practical example.)
Proposed resolution
Merge the max-age of the existing redirecting cache item plus that of the current render array that is causing the redirecting cache item to be updated.
Remaining tasks
Review.
User interface changes
None.
API changes
None.
Comment | File | Size | Author |
---|---|---|---|
#21 | cache_redirect_max_age-2463581-21.patch | 12.45 KB | Wim Leers |
Comments
Comment #1
swentel CreditAttribution: swentel commentedSo, is it really only this ?
Comment #2
Fabianx CreditAttribution: Fabianx for Acquia commentedYes, it is. We probably should add some tests though this being a bug ...
Comment #3
Wim LeersThis will be able to copy/paste the test coverage added in #2493047: Cache redirects should be stored in the same cache bin and adjust it.
What I'm missing here is a thorough explanation for why we want to cache contexts permanently.
E.g.:
Then my question is: why should context C be permanently included in the cache redirect?
Comment #4
Fabianx CreditAttribution: Fabianx for Acquia commentedThe problem is that currently the last set 'wins'.
So if we wanted to support that, we would need to take the mergeMaxAge() of all the max-ages that could be present and track those somehow, which is way more complicated than just making it permanent.
Comment #5
Wim LeersAha! Good point. The last max-age indeed always wins.
But we can easily retrieve the previous max-age: if the cache item's
expired === -1
, then it wasCache::PERMANENT
. Otherwise, it isexpire - created
. Then we can useCache::mergeMaxAges()
.Or what am I missing?
Comment #6
Wim Leers#2493047: Cache redirects should be stored in the same cache bin landed, which makes it much easier to write the necessary test coverage in this issue.
Comment #7
Wim LeersEt voila. A simple, elegant patch, thanks to all of the refactoring that went into
RenderCache
. And thanks to the test coverage that has been refined in #2493047: Cache redirects should be stored in the same cache bin and other issues, adding the necessary test coverage is also incredibly easy :)Comment #8
Wim LeersUpdate per #3 + #4.
Comment #9
Wim LeersComment #11
Wim LeersRebased. Conflicted with #2483781: Move cache contexts classes from \Drupal\Core\Cache to \Drupal\Core\Cache\Context.
Comment #12
Fabianx CreditAttribution: Fabianx for Acquia commentedRTBC, looks great to me! :)
Comment #13
catchThis could use additional documentation I think.
Based on comment #3, the redirect cache item always needs to have a TTL that is the same as the shortest redirected cache item at any one time - so that it expires when any of them do (in case things change on the expiry).
What we're essentially doing is bubbling max ages of cache contexts to cache redirect items - that's a lot of concepts to keep straight all at once.
Comment #14
Wim Leers#13 It's just merging the cacheability metadata of the existing cache redirect (if any) with what would be written to the updated cache redirect. HEAD is already doing this for cache contexts and cache tags. All this patch does, is also do it for max-age. And hence, just do it for all bits of cacheability metadata. That's why this patch is able to simplify things.
Back to RTBC for more maintainer feedback.
Comment #17
Wim LeersTest failures were not reproducible locally. Betting it was a testbot thing.
Comment #19
Wim LeersWas broken by #2511472: Refactor all usages of drupal_render()/Renderer::render() that break #2450993.
Rebased, conflict automatically resolved by git.
Comment #20
catch@Wim yes I understand #14 but I think we should add extra docs explaining why exactly we have to do it.
Comment #21
Wim LeersDone.
Comment #22
catchCommitted/pushed to 8.0.x, thanks!