In D7 core has started to misuse its own API call hook_flush_caches to do lots of mainenance work. The same is starting to happening with D6 with recent patches that did go in for 6.22.

As the main conception of hook_flush_caches in contrib and core is now that "you can use this to know when caches are cleared", it is quite clear that system_cron should not call this hook.

If you still want to do something on system_cron, use hook_cron.

The idea is to cache the bins directly after clearing the cache (cache_clear_all() in includes/common.inc) in a cache-variable and have system cron use that one instead of running hook_flush_caches.

Of course if the variable is empty, it would still need to call it, but could then at least cache it.

But this would remove 95% of all unncesseary calls to hook_flush_caches.

I also propose changing the docs to reflect that it is now okay, to use hook_flush_caches to know when the cache is cleared and to officially allow this as there are so many occurences that are using this or will need to use this. This is not an API change, but a change reflecting the reality of how the API is used.

There absolutely is a need for this hook and cleaning up system.module, which is just expiring old cache items would allow doing this.

Best Wishes,

Fabian

Comments

catch’s picture

Category: feature » bug

Subscribing. This is a bug as well, the code does not match the documentation at all.

milodesc’s picture

Issue summary: View changes
fabianx’s picture

Priority: Normal » Major

That is actually a pretty good idea I had there how to solve this long standing problem.

I completely forgot about that though :D.

catch’s picture

Title: system_cron should not run hook_flush_caches, but use a cached version » system_cron() should not run hook_flush_caches(), but use a cached version
Version: 8.0.x-dev » 7.x-dev
Issue tags: +Performance

Hook doesn't exist in 8.x.

Replaced by:

https://api.drupal.org/api/drupal/core!core.api.php/function/hook_cache_...

And it's not invoked on cron. We get the list of cache bins for garbage collection without any hook invocations.

Moving back to 7.x, still an issue there.

klausi’s picture

Status: Active » Needs review
Issue tags: +Needs tests
StatusFileSize
new1.17 KB

Here we go.

fabianx’s picture

Status: Needs review » Reviewed & tested by the community

RTBC - Great patch, klausi!

klausi’s picture

Status: Reviewed & tested by the community » Needs work
Issue tags: -Needs backport to D7

errrr, yeah - now we only need tests.

I propose that we create a system_cron_test.module that implements hook_flush_caches() and set a variable there. Then we invoke drupal_cron_run() in the test, assert that the variable was set the first time, reset it, call drupal_cron_run() a second time and assert that now the variable does not get set.

Removing backport tag, since there was never a D8 version of this change.

klausi’s picture

Status: Needs work » Needs review
StatusFileSize
new2.64 KB

And now with test case.

Status: Needs review » Needs work

The last submitted patch, 8: drupal-system_cron-1191290-8.patch, failed testing.

The last submitted patch, 8: drupal-system_cron-1191290-8.patch, failed testing.

klausi’s picture

Status: Needs work » Needs review
StatusFileSize
new3.55 KB

Of course it helps to also include the test module in the patch, sorry.

fabianx’s picture

Status: Needs review » Reviewed & tested by the community

RTBC - looks great to me! Tests look good.

David_Rothstein’s picture

Status: Reviewed & tested by the community » Needs review
StatusFileSize
new3.83 KB
new2.04 KB

I tested this patch but it didn't quite work correctly because there is no code that clears the cache. So for example, after a programmatic module_enable(), the next cron run won't pick up that module's cache tables. (It's only an issue for programmatic module enables because other methods for turning on modules wind up calling drupal_flush_all_caches() anyway.)

It actually looks like the tests had a workaround for that, so here's a new patch with a cache clear added to the codebase and removed from the tests.

I also changed the code comment a bit to be more general and not to refer to specific contrib modules, since those could change at some point.

It looks good to me otherwise though.

David_Rothstein’s picture

Also, do we want to do this (from the issue summary) here?

I also propose changing the docs to reflect that it is now okay, to use hook_flush_caches to know when the cache is cleared and to officially allow this as there are so many occurences that are using this or will need to use this. This is not an API change, but a change reflecting the reality of how the API is used.

joelpittet’s picture

Status: Needs review » Reviewed & tested by the community
Issue tags: -Needs tests

Awesome thanks for testing the programmatic module_enable()

Re #14 I'll let @Fabianx respond to that bit as he proposed it. I'll ping him.

David_Rothstein’s picture

Status: Reviewed & tested by the community » Fixed
Issue tags: +7.42 release notes

Committed to 7.x - thanks!

I think we can leave changing the docs to a possible followup, if desired. For now I'm OK with the scenario where we continue not to recommend running cache clearing operations in that hook... but secretly support it anyway :)

  • David_Rothstein committed e6e00e8 on 7.x
    Issue #1191290 by klausi, David_Rothstein, Fabianx: system_cron() should...
fabianx’s picture

#16: I do agree, that we can keep it inofficial.

I am glad the idea has made it in :).

Status: Fixed » Closed (fixed)

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