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.
Updated: Comment #N
Problem/Motivation
Using \Drupal::state()->set('menu_rebuild_needed')
indicates that the menu (router) needs rebuilding, but helps ensure it is only done once per request.
However, the code that checks for the flag and does the rebuilding is in menu_get_item()
, which is being called less and less.
This means that the menu will only rebuilt on the next call to menu_get_item()
, and you don't know when that will be.
Proposed resolution
Move that check and rebuilding to a listener, probably for KernelEvents::RESPONSE?
Remaining tasks
Decide on approach, write patch
User interface changes
N/A
API changes
N/A
Comment | File | Size | Author |
---|---|---|---|
#3 | state-2167323-3.patch | 3.18 KB | tim.plunkett |
Comments
Comment #1
tim.plunkettComment #2
tim.plunkettComment #3
tim.plunkettHere is one approach. Works for failure I saw in another issue (#2042807: Convert search plugins to use a ConfigEntity and a PluginBag).
Comment #5
Crell CreditAttribution: Crell commentedRESPONSE isn't a good place for this; that blocks the user response.
However, here's a possibility. Wherever it is that we trigger the need for a menu rebuild... don't set state at all. Set an anonymous function event listener for kernel::TERMINATE. That way it fires after the response is set, but in the same process. No need to wait for the next request, we simply punt it to the end of the current process. No state tracking needed.
We can probably put the actual logic into a service, and have the closure simply call that. That way we can still unit test it. I know we did something very similar elsewhere a while back, but I can't recall where. It was a ParisLiakos patch, I think...
Comment #6
catchThis was originally added by #202955: Access denied after install - menu_rebuild() calls to workaround calling menu_rebuild() in an incomplete environment during the installer. We have installer tests now, so moving it to the end of the request rather than the next request ought to maintain the performance improvement without regressing the bug. If it doesn't while the installer isn't much better than it was this was introduced, it ought to be more fixable in there.
Comment #7
tim.plunkettOkay I like the approach in #2164367: Rebuild router as few times as possible per request better.