Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rebuild the Drupal route cache. #19906

Merged
merged 1 commit into from
Mar 26, 2021
Merged

Rebuild the Drupal route cache. #19906

merged 1 commit into from
Mar 26, 2021

Conversation

homotechsual
Copy link
Contributor

@homotechsual homotechsual commented Mar 25, 2021

Overview

This is linked to issue 158 and issue 37.

It takes an alternative approach to #19888, adding a Utils/System function to rebuild the routes which we can then invoke from multiple places if required with an invocation added to the rebuildMenuandCaches function in invoke.php.

Before

Enabling a CiviCRM extension that adds a route on Drupal 8 or 9 results in a 404 until the routes are rebuilt in Drupal.

After

Enabling/disabling an extension rebuilds Drupal's routes and routes added in CiviCRM work as expected..

Technical Details

There might be a more performant option for this but I can't find anything...

@civibot
Copy link

civibot bot commented Mar 25, 2021

(Standard links)

@civibot civibot bot added the master label Mar 25, 2021
@homotechsual
Copy link
Contributor Author

Alternative approach for #19888

@homotechsual
Copy link
Contributor Author

@demeritcowboy
Copy link
Contributor

demeritcowboy commented Mar 25, 2021

I think what @seamuslee001 meant on the other PR by CRM_Utils_System_x classes is that instead of hardcoding Drupal8, here in Invoke you would call $config->userSystem->invalidateRouteCache() and in CRM_Utils_System_Base you would put a do-nothing function invalidateRouteCache() { } and in CRM_Utils_System_Drupal8 you would override that function.

@homotechsual
Copy link
Contributor Author

I think what @seamuslee001 meant on the other PR by CRM_Utils_System_x classes is that instead of hardcoding Drupal8, here in Invoke you would call $config->userSystem->invalidateRouteCache() and in CRM_Utils_System_Base you would put a do-nothing function invalidateRouteCache() { } and in CRM_Utils_System_Drupal8 you would override that function.

That makes sense.

@homotechsual
Copy link
Contributor Author

Refactored with @demeritcowboy 's suggested route and squashed.

CRM/Core/Invoke.php Outdated Show resolved Hide resolved
@demeritcowboy
Copy link
Contributor

I tested this in drupal 9 with cdntaxreceipts but I still needed to clear drupal cache after in order to avoid the "page not found". Hmmmm.

@homotechsual
Copy link
Contributor Author

I tested this in drupal 9 with cdntaxreceipts but I still needed to clear drupal cache after in order to avoid the "page not found". Hmmmm.

If you switch it out to do \Drupal::service('router.builder')->rebuild(); do you have to clear the Drupal Cache?

This is linked to [issue 158](https://lab.civicrm.org/dev/drupal/-/issues/158) and [issue 37](https://lab.civicrm.org/dev/drupal/-/issues/37).

It takes an alternative approach, adding a Util hook function to rebuild the route cache which we can then invoke from multiple places.
Trigger `rebuildDrupalRouteCache()` when running `triggerRebuild()`
Fix checkstyle issues
Change function from `protected` to `public`
Update Drupal8.php
Add base for `invalidateRouteCache()`
Add invalidateRouteCache function
Add call to userFramework->invalidateRouteCache
Update Base.php
Correct `userFramework` to `userSystem`
Remove stray whitespace.
Move invalidateRouteCache call to the same place as resetNavigation.
Update Invoke.php
Switch to the `router.builder' option as invalidating the cache doesn't cut it.
@homotechsual
Copy link
Contributor Author

Okay this works now, it turns out we do need to do a router.builder rebuild for this to work!

@demeritcowboy
Copy link
Contributor

Ok neat. I guess we're then back to where is the best place. So this would trigger on any extension action even disable but maybe that's ok/desired.

@homotechsual
Copy link
Contributor Author

Yeah, I'm thinking that having extension routes in the cache post-disable is undesirable so it's cleaner to run this on any extension enable/disable/install/uninstall.

@homotechsual homotechsual changed the title [WIP] Rebuild the Drupal route cache. Rebuild the Drupal route cache. Mar 25, 2021
@demeritcowboy
Copy link
Contributor

  • General standards
    • [r-explain] PASS
    • [r-user] PASS
    • [r-doc] PASS
    • [r-run] PASS
  • Developer standards
    • [r-tech] PASS
      • It seems like this would only be called during extension lifecycle events or some already heavy cache clearing event. I can't think of a better place to put it unless it's left to extensions to decide when to do it.
    • [r-code] PASS
      • I don't know that it needs to call class_exists('\Drupal') given that this is already within a drupal8-only file. Ditto hasContainer() although I suppose that call might be a safeguard against some weird edge case.
    • [r-maint] ?
    • [r-test] PASS

@homotechsual
Copy link
Contributor Author

I went with checking for \Drupal and ->hasContainer() because the cost is minimal of those checks and it would catch any possible scenario where this tries to get invoked during installs or in situations where Drupal isn't booted yet.

@eileenmcnaughton
Copy link
Contributor

Thanks for the review @demeritcowboy - I think the r-maint is OK since it's just a little bit of code that seems pretty readable

@eileenmcnaughton eileenmcnaughton merged commit 93f40fc into civicrm:master Mar 26, 2021
@eileenmcnaughton
Copy link
Contributor

@MikeyMJCO this is 'linked to issues' - are they closable now or just linked

@homotechsual
Copy link
Contributor Author

Closeable along with PR #19888

@homotechsual homotechsual deleted the patch-8 branch March 26, 2021 10:47
@homotechsual
Copy link
Contributor Author

@MikeyMJCO this is 'linked to issues' - are they closable now or just linked

Issues and other PR closed :-)

@eileenmcnaughton
Copy link
Contributor

thanks

@eileenmcnaughton
Copy link
Contributor

@MikeyMJCO - although I see I said above the code is pretty readable I'm reading it now & I'm confused :-)

Specifically I don't understand why it's nested in the if trigger part here - because it seems the line is about rebuilding paths which is 'all the rest of the function' rather than re-instating logging

image

If it IS correct for it to be in that loop maybe you could add a PR to explain why it should only be done when rebuilding mysql triggers

@homotechsual
Copy link
Contributor Author

It's a computationally very expensive operation - like rebuilding triggers. It's not something that should be called as often as we flush caches - the performance cost would be very high.

When we do things like disable/enable or upgrade extensions we're already setting triggerRebuild to TRUE so it felt more appropriate to put it in that conditional than call it any time we rebuild the cache.

CRM_Core_Invoke::rebuildMenuAndCaches(TRUE);

@homotechsual
Copy link
Contributor Author

Described in comments in #20414

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants