The query performed in menu_contextual_links() that fetches all router items (e.g., node/%/edit) for a certain base router path (e.g., node/%) always leads to the same result for a certain path.

It easily can be cached, which further reduces the queries performed when putting 'cache_menu' in a fast cache backend.

Comments

sun’s picture

StatusFileSize
new4.62 KB

Still the same overall logic, but heavily improved + clarified. No functional changes.

moshe weitzman’s picture

This pattern is going to drive me to drink.

We have a single table query here with all the right indices. There is normally no reason to cache this. But folks abuse the caching layer as a way to avoid using the DB at all. Cachein, and especially persistent cache, is not free. It introduces up thorny invalidation/expiration issues.

I'm not going to actively block this, but I won't promote it either.

moshe weitzman’s picture

Category: bug » feature
sun’s picture

@moshe: I've to agree with you, and am equally baffled by the introduction of so many separate and manually built caches throughout D7, leading to lots of duplicate code, no clear pattern, and the potential of invalidation/expiration problems. We should have done #636454: Cache tag support prior to introducing all those caches, but it seems several core contributors wanted to make core perform faster for sites leveraging a fast in-memory cache (so as to not hit the database even once for simple, regular requests), regardless of that cache invalidation API. For that sake, I'm just continuing that idea here.

In this case, there should not be any invalidation/expiration issue, as the data is cached in {cache_menu}, which is used for identical cache data by the menu system, and already cleared at the right times.

sun’s picture

Although my local box is totally not suitable for doing benchmarks, I've mass-applied the following range of current performance patches and am getting a nice boost:

#910190: Entire schema cache needlessly loaded on all pages
#910156: Remove 'description' keys from schema cache
#606966: 'load arguments' of parent path are not inherited
#910124: Clean up menu_contextual_links()

BEFORE patches:
Executed 36 queries in 25.18 ms.
Page execution time was 481.48 ms.
Memory used at: devel_boot()=2.5 MB, devel_shutdown()=16.23 MB, PHP peak=16.75 MB.

AFTER patches:
Executed 35 queries in 15.99 ms.
Page execution time was 471.18 ms.
Memory used at: devel_boot()=1.95 MB, devel_shutdown()=15.85 MB, PHP peak=16.5 MB.

Test page: admin/config/development/devel; Garland; enabled Navigation menu block containing 1 taxonomy term link and 1 node link.

moshe weitzman’s picture

thats fine, but you didn't get that from removing a single fully indexed query which is whats proposed here.

fyi, i don't think that invalidation API is really the answer for this fixing this anti-pattern. people really need to trust their database (and refactor queries which make their DB unstable).

catch’s picture

I don't think the cache invalidation API solves the 'caching single indexed queries' either, what I will say is that on benchmarks on ex2 only two types of queries show up in the MySQL slow query log:

1. cache misses for queries that are cached (usually things that can only be cached per page, and the load tests only return to something like 5-10% of pages per run if that)
2. a few queries like node_get_types() that aren't cached.

Additionally, while you can scale MySQL for reads via replication, you can only do that for slave-safe queries - that's not the case for queries on any system-level information like the menu system, system table, field configuration which always need to be up-to-date. memcache, while it needs to be cleared at the right time, doesn't suffer from replication lag. So while these patches don't result in a significant performance improvement for an individual request, they do result in being able to scale to a much higher number of requests per second before hitting the limits of MySQL.

Having said that, generally the only people able to view contextual links are going to be authenticated users with some kind of additional permissions, so I'm not sure that argument holds in this case. Generally I've restricted query culling to things which run for anonymous users with no page caching.

moshe weitzman’s picture

Status: Needs review » Closed (won't fix)

catch's argument about not messing with admin/authenticated features like contextual links is pretty compelling.

that makes sense that this anti-pattern is useful for scaling and not page speed. but i still think you have to attack the root cause which are queries that are gumming up mysql. if you don't attack root cause, you end up where we are now which is afraid to depend on your database. you start caching the hell out out of your app which is hard for invalidation, testing, debugging.

sun’s picture

Title: menu_contextual_links() queries are not cached » Clean up menu_contextual_links()
Category: feature » task
Status: Closed (won't fix) » Needs review
Issue tags: -Performance
StatusFileSize
new4.23 KB

Thanks for the clarification.

But, ugh, I took the chance to quite heavily clean up that menu_contextual_links() function, which I'd still like to get in.

sun’s picture

Version: 7.x-dev » 8.x-dev
Assigned: sun » Unassigned

Although badly needed, this is D8 material according to the rules (I had to learn today). It may be backported at a later point in time (though that's unlikely).

kscheirer’s picture

Status: Needs review » Needs work

The last submitted patch, drupal.menu-contextual-links.9.patch, failed testing.

Version: 8.0.x-dev » 8.1.x-dev

Drupal 8.0.6 was released on April 6 and is the final bugfix release for the Drupal 8.0.x series. Drupal 8.0.x will not receive any further development aside from security fixes. Drupal 8.1.0-rc1 is now available and sites should prepare to update to 8.1.0.

Bug reports should be targeted against the 8.1.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.2.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.1.x-dev » 8.2.x-dev

Drupal 8.1.9 was released on September 7 and is the final bugfix release for the Drupal 8.1.x series. Drupal 8.1.x will not receive any further development aside from security fixes. Drupal 8.2.0-rc1 is now available and sites should prepare to upgrade to 8.2.0.

Bug reports should be targeted against the 8.2.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.3.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.2.x-dev » 8.3.x-dev

Drupal 8.2.6 was released on February 1, 2017 and is the final full bugfix release for the Drupal 8.2.x series. Drupal 8.2.x will not receive any further development aside from critical and security fixes. Sites should prepare to update to 8.3.0 on April 5, 2017. (Drupal 8.3.0-alpha1 is available for testing.)

Bug reports should be targeted against the 8.3.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.4.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.3.x-dev » 8.4.x-dev

Drupal 8.3.6 was released on August 2, 2017 and is the final full bugfix release for the Drupal 8.3.x series. Drupal 8.3.x will not receive any further development aside from critical and security fixes. Sites should prepare to update to 8.4.0 on October 4, 2017. (Drupal 8.4.0-alpha1 is available for testing.)

Bug reports should be targeted against the 8.4.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.5.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.4.x-dev » 8.5.x-dev

Drupal 8.4.4 was released on January 3, 2018 and is the final full bugfix release for the Drupal 8.4.x series. Drupal 8.4.x will not receive any further development aside from critical and security fixes. Sites should prepare to update to 8.5.0 on March 7, 2018. (Drupal 8.5.0-alpha1 is available for testing.)

Bug reports should be targeted against the 8.5.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.6.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.5.x-dev » 8.6.x-dev

Drupal 8.5.6 was released on August 1, 2018 and is the final bugfix release for the Drupal 8.5.x series. Drupal 8.5.x will not receive any further development aside from security fixes. Sites should prepare to update to 8.6.0 on September 5, 2018. (Drupal 8.6.0-rc1 is available for testing.)

Bug reports should be targeted against the 8.6.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.7.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.6.x-dev » 8.8.x-dev

Drupal 8.6.x will not receive any further development aside from security fixes. Bug reports should be targeted against the 8.8.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.9.x-dev branch. For more information see the Drupal 8 and 9 minor version schedule and the Allowed changes during the Drupal 8 and 9 release cycles.

Version: 8.8.x-dev » 8.9.x-dev

Drupal 8.8.7 was released on June 3, 2020 and is the final full bugfix release for the Drupal 8.8.x series. Drupal 8.8.x will not receive any further development aside from security fixes. Sites should prepare to update to Drupal 8.9.0 or Drupal 9.0.0 for ongoing support.

Bug reports should be targeted against the 8.9.x-dev branch from now on, and new development or disruptive changes should be targeted against the 9.1.x-dev branch. For more information see the Drupal 8 and 9 minor version schedule and the Allowed changes during the Drupal 8 and 9 release cycles.

Version: 8.9.x-dev » 9.2.x-dev

Drupal 8 is end-of-life as of November 17, 2021. There will not be further changes made to Drupal 8. Bugfixes are now made to the 9.3.x and higher branches only. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 9.2.x-dev » 9.3.x-dev

Version: 9.3.x-dev » 9.4.x-dev

Drupal 9.3.15 was released on June 1st, 2022 and is the final full bugfix release for the Drupal 9.3.x series. Drupal 9.3.x will not receive any further development aside from security fixes. Drupal 9 bug reports should be targeted for the 9.4.x-dev branch from now on, and new development or disruptive changes should be targeted for the 9.5.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 9.4.x-dev » 9.5.x-dev

Drupal 9.4.9 was released on December 7, 2022 and is the final full bugfix release for the Drupal 9.4.x series. Drupal 9.4.x will not receive any further development aside from security fixes. Drupal 9 bug reports should be targeted for the 9.5.x-dev branch from now on, and new development or disruptive changes should be targeted for the 10.1.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

smustgrave’s picture

Issue summary: View changes
Status: Needs work » Postponed (maintainer needs more info)

Wonder if this is still needed for D10?

avpaderno’s picture

menu_contextual_links() does not exist in Drupal 9.5. Either the issue summary needs to be updated, or this issue can be closed because there is not a function/method that contains the code that was in menu_contextual_links().

avpaderno’s picture

I guess that code should be now in the ContextualLinkManager class which, as other plugin managers, uses a cache already.

smustgrave’s picture

Status: Postponed (maintainer needs more info) » Closed (outdated)

Agreed. Think this can be closed then. If anyone disagrees please reopen updating issue summary for D10

Thanks!