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
#2428563-20: Introduce parameter-dependent cache contexts
See #3.
Proposed resolution
See #3.
Remaining tasks
Do it.
User interface changes
None.
API changes
None.
Beta phase evaluation
Issue category | Task, because this is a hardening against a theoretical bug that would only occur under very special circumstances. |
---|---|
Issue priority | Normal because very unlikely circumstances, but the hardening is still important. |
Prioritized changes | The main goal of this issue is to be a follow-up from major / critical tasks - when cache contexts had been introduced (that issue was open since then) and to reduce fragility in that currently theoretically two cache contexts could return the same value and then theoretically a cache item could be wrongly retrieved. This hardens against this case and also as non-prioritized side-effect improves DX. |
Disruption | Almost zero disruption. For 99% of developers, zero disruption. The sole exception: the very few tests that actually test that caching of something that is rendered is working by hardcoding a cache ID. Those are very easy to update, as the patch shows. |
Comment | File | Size | Author |
---|---|---|---|
#39 | 2430397-39.patch | 7.34 KB | Wim Leers |
Comments
Comment #1
cosmicdreams CreditAttribution: cosmicdreams commentedHi I just found this issue. Please forgive the naive questions:
1. Does CacheContext order matter? Some implementations sort their contexts, some append a new context to the end of a list. There are a lot the send a static value.
2. Does #2428563-20: Introduce parameter-dependent cache contexts Primarily discuss a change to the CacheContext tests?
3. What are the next steps here?
Comment #2
Wim LeersAFAICT this is about this bit in #2428563-20: Introduce parameter-dependent cache contexts:
There's no need to standardize: what matters is that we get back a string, that somehow uniquely identifies this specific cache context. If we're going to also impose a strong structure on the value of the cache context, we're A) not gaining anything noteworthy, B) making things more complex.
What matters is that given a certain cache context, you get back a certain string of data. That's it. As long as that string makes sense within the context (heh…) of that cache context, that's fine.
That final bit, about calculating the cache contexts from a CID, I think a small desire to be able to do that, is what caused this confusion (and this very issue). But there is no way that that is possible. It's perfectly plausible that two different cache contexts return the exact same value. e.g.
#cache => ['keys' => ['foo', 'bar'], 'contexts' => ['color_of_the_day', 'user.favorite_color']]
may very well result in a CID offoo:bar:blue:blue
. How are you ever going to know which belongs to which?#1:
AFAICT, it's safe to close this. Feel free to reopen if I was wrong.
Comment #3
Fabianx CreditAttribution: Fabianx as a volunteer and at Tag1 Consulting commentedAnd that was my exact use-case:
if cache contexts are standardized to return the value we can do:
OR
OR
OR
...
to help with debuggability instead of every cache context having to take care of that (and some do, others don't).
At least looking at DB tables.
r.* or theme.bartik was always nicely visible of where it came from while for 'blue' it would not be ...
But adding:
theme=[theme] we now would end up with:
theme=theme.bartik, which does not hurt, but is a little redundant.
Does that make my intent more clear?
Comment #4
Wim LeersYes, that hugely clarifies things.
Will post a patch tomorrow
Comment #5
Wim LeersUnit tests pass, a targeted selection of integration tests pass. But quite possibly there will still be some failures. Let's see what testbot has to say!
Comment #6
Fabianx CreditAttribution: Fabianx as a volunteer and at Tag1 Consulting commentedLooks great to me. Lets ensure using a database inspector does show those [] cases and that we don't need additional escaping, when using e.g. a WHERE query, besides that:
Great idea with the [token]=value :)!
Comment #7
Wim LeersThat's indeed a boon for DX. Manually checked, and confirmed that this works without any nasty surprises.
Comment #9
Wim LeersTestbot, you're really driving me insane.
Comment #12
Wim LeersFAILED: [[SimpleTest]]: [PHP 5.4 MySQL] Setup environment: failed to clear checkout directory.
Re-testing again.
Comment #19
Wim LeersAhh, finally sane failures :) Fixing!
Comment #20
Wim LeersShould be green & RTBC'able.
Comment #21
Fabianx CreditAttribution: Fabianx as a volunteer and at Tag1 Consulting commentedLOVE IT!
The last interdiff already shows why this is really awesome! :)
Comment #22
alexpottThis issue is a task so we need to outline how it fits within the allowable Drupal 8 beta criteria. Can someone add Drupal 8 beta phase evaluation template to the issue summary.
Comment #23
Wim LeersBeta evaluation added. Sorry for not having done it already!
Comment #25
Wim LeersRebased. No conflicts.
Comment #27
Wim LeersRebased. Trivial conflict with #2511472: Refactor all usages of drupal_render()/Renderer::render() that break #2450993.
Comment #28
alexpottThe change makes a lot of sense but the beta evaluation needs work since DX is not a permitted reason for a change.
Comment #29
Fabianx CreditAttribution: Fabianx as a volunteer and at Tag1 Consulting commentedWanted to re-classify as bug, even if rare, it is possible for a cache context to return the same value and then it could happen that the wrong item is retrieved, which could lead to cache mismatch, because it depends on the order. (it is a rare occurence, but similar to config's getCacheSuffix()).
But I can't think of how to write the test coverage for that (and if ther really is a bug), but it reduces fragility in that it hardens the cache keys.
Comment #30
Fabianx CreditAttribution: Fabianx as a volunteer and at Tag1 Consulting commentedComment #32
yched CreditAttribution: yched commentedWell, it's not only about DX, right, but also site-builder understability / debuggability of what happens on the render cache ?
Also, disruption is null anyway ?
Anyway, big +1 on that change :-)
Comment #33
Wim LeersThis is a straight reroll.
I'd argue that's DX? :) How many site builders are going to analyze the render cache? Aren't they developers at that point?
Yes, with the exception if very very minor disruption in tests (as the patch shows, and the beta evaluation indicates).
Yay :)
Comment #35
Fabianx CreditAttribution: Fabianx as a volunteer and at Tag1 Consulting commentedComment #36
Wim Leers#2493033: Make 'user.permissions' a required cache context landed yesterday and caused the conflicts resulting in the test failure.
But! It actually fixed things in a generic way, so the patch here simply becomes smaller :)
Comment #37
Fabianx CreditAttribution: Fabianx as a volunteer and at Tag1 Consulting commentedBack to RTBC
Comment #39
Wim LeersConflicted with #2351015: URL generation does not bubble cache contexts, which landed yesterday. Easy conflict resolution.
Comment #40
alexpottCommitted ba1b14e and pushed to 8.0.x. Thanks!
Thanks for adding the beta evaluation.
Comment #42
Wim LeersUpdated https://www.drupal.org/developing/api/8/cache/contexts accordingly.
Comment #44
Josh Waihi CreditAttribution: Josh Waihi commentedIs this function really suppose to return a 0 if $role is in the user roles? Because it produces stranges things like user.roles:authenticated=1 for anonymous pages.