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

Comments

drclaw created an issue. See original summary.

agentrickard’s picture

Status: Needs review » Postponed (maintainer needs more info)

How can I reproduce this issue for testing?

abramm’s picture

Status: Postponed (maintainer needs more info) » Needs review
StatusFileSize
new1.1 KB

I 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.

agentrickard’s picture

Thanks. I've been on vacation and will take a look next week.

agentrickard’s picture

StatusFileSize
new94.28 KB

I don't understand what I'm looking for here. renderviz doesn't seem to be returning useful information.

See attached.

abramm’s picture

Hi @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.

agentrickard’s picture

Thanks! That's an awesome tool.

agentrickard’s picture

I 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.

<!--{"contexts":["user.permissions"],
"tags":["config:domain.record.two_example_com","node:1","node:2","config:system.menu.my-menu"],
"max-age":-1}-->
agentrickard’s picture

StatusFileSize
new1.09 KB

I wonder if this approach would also work?

agentrickard’s picture

I 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.

abramm’s picture

I 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.

abramm’s picture

Just 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.

agentrickard’s picture

I'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.

luksak’s picture

StatusFileSize
new1.08 KB

The 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.

agentrickard’s picture

Thanks!

agentrickard’s picture

Sorry, 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?

agentrickard’s picture

I can't reproduce the cache tag / renderviz issue. I'm tempted to commit this.

agentrickard’s picture

Status: Needs review » Fixed

Committed.

  • agentrickard committed d18aec9 on 8.x-1.x authored by abramm
    Issue #2958644 by agentrickard, abramm, drclaw, Lukas von Blarer:...

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.