When building out menu trees' render arrays (e.g. in a menu block), the access check in DomainAccessCheck gets applied to any links with a route. And since that check sets the max-age of the result to 0, none of the menu blocks are render-cacheable (once the menu link cacheability is all merged and bubbled up).
I can think of a couple potential solutions to this issue:
1. Add a cache context of url.site to the access result instead of setting the max age.
Since we invalidate url.site when domain config is saved, we can expect that if a domain becomes disabled, the access results will be re-checked
2. Add needs_incoming_request to the service definition tags
I suspect that this check is really only for incoming requests? This seems like the simplest solution to me, but there may be other reasons to perform the access check all the time. I've attached a patch in case it makes sense (simple one-liner).
Thanks!
drclaw
| Comment | File | Size | Author |
|---|---|---|---|
| #14 | 2958644-cache-tags-14.patch | 1.08 KB | luksak |
| #9 | 2958644-cache-tags-9.patch | 1.09 KB | agentrickard |
| #5 | Screen Shot 2018-06-18 at 2.56.09 PM.png | 94.28 KB | agentrickard |
| #3 | domain-incorrect_access_check_result_cache_metadata-2958644-3.patch | 1.1 KB | abramm |
| domain-access_check_needs_incoming_request-0.patch | 528 bytes | drclaw |
Comments
Comment #2
agentrickardHow can I reproduce this issue for testing?
Comment #3
abrammI think changing '->setCacheMaxAge(0)' to '->addCacheableDependency($domain)' should be enough; cache dependencies will do the rest.
Steps to reproduce:
1) Create a custom menu.
2) Add menu link to a node.
3) Add menu block to the page.
4) Optionally, install/enable renderviz module and ensure block max-age is 0 (should be -1 normally).
Resolving the menu link access will lead to resolving the node_view access check which in turn calls '\Drupal\domain\Access\DomainAccessCheck::access()'.
Please try this patch drclaw.
Comment #4
agentrickardThanks. I've been on vacation and will take a look next week.
Comment #5
agentrickardI don't understand what I'm looking for here. renderviz doesn't seem to be returning useful information.
See attached.
Comment #6
abrammHi @agentrickard,
Sorry I wasn't clear enough.
Try checking the page source HTML; renderviz adds some debugging comments in a way similar to how Twig debug does. I don't think obtaining max-age via renderviz js is possible.
You should see max-age 0 without a patch and -1 + cache metadata (most notably domain record context) with patch applied.
Comment #7
agentrickardThanks! That's an awesome tool.
Comment #8
agentrickardI am consistently seeing the cache tag applied to the first loaded domain (in this case two.example.com) and then appearing the same when one.example.com is loaded.
This is identical on both one.example.com and two.example.com for an anonymous user.
Comment #9
agentrickardI wonder if this approach would also work?
Comment #10
agentrickardI think the above url.site approach will work. I _think_ the other fails because we don't set unique cache contexts per domain since the url.site core tag handles it for us.
Comment #11
abrammI would rather stick with adding domain as a cache dependency and here's why.
You never know what 3rd party custom module may do. Imagine someone wants to replace the active domain based on permissions or user roles or phase of the moon; the 'url.site' approach will not work since the developer may extend domain entity and expect cache metadata to bubble properly.
However, I think we should investigate why you're getting the cache tag from a domain which is different to active one.
Did you really access the site using a different domain (e.g. url.site) or did you just change the default domain? That may be a different bug; could you please write simple steps to reproduce? I'm going on a vacation for 2 weeks but I could have a look after I'm back.
Comment #12
abrammJust thought. In any case, simply adding a context is not enough since anything rendering within a domain should depend on a domain settings. So we need the 'config:domain.record.name' cache tag in any case which is normally supplied by cache dependency.
Comment #13
agentrickardI'm switching domains as anon user via the Domain Switcher block.
Steps to reproduce:
1) Install Domain and create five domains.
2) Create a custom menu.
3) Create and add menu link to a node.
4) Add menu block to the page.
5) Enable renderviz
6) Enable the Domain Switcher block
7) Give anon users access to the Domain Switcher block
8) Click from domain to domain and check the output of renderviz
Not sure about the $domain dependency for 3rd parties. url.site provides the same context and is recommended for use with Domain Config.
This is all on a standard profile installation of Drupal 8.6.
Comment #14
luksakThe patch failed to apply using composer. Here is a re-roll without changes.
Apart from that the patch solve a significant performance issue on a production site.
In case there are no open tasks like tests etc here, I'd RTBC this patch.
Comment #15
agentrickardThanks!
Comment #16
agentrickardSorry, looking at this again, we still have to validate that the proper cache tags are being applied. Comments #8 and #13 are why we haven't committed this yet.
Can you confirm that caching is being applied as expected?
Comment #17
agentrickardI can't reproduce the cache tag / renderviz issue. I'm tempted to commit this.
Comment #18
agentrickardCommitted.