Overview
authorTim Otten <totten@civicrm.org>
Sat, 28 Jul 2018 22:31:20 +0000 (15:31 -0700)
committerTim Otten <totten@civicrm.org>
Sat, 28 Jul 2018 23:30:53 +0000 (16:30 -0700)
----------------------------------------

`CRM_Utils_System::flushCache()` calls `CRM_Utils_Cache::singleton()->flush()`.
In `5.3`, this triggered a cascading effect; in development of `5.4.alpha`,
some of the cascades were overzealous and we revised to get tighter control
over cascading.

With an aim to being conservative and reproducing old behavior, I previously
patched `5.4.alpha` to add several extra flushes and simulate the old cascades.
However, it wasn't really as conservative as hoped -- because the "old
behavior" depended on the environment.  This patch brings us closer the "old
behavior".

See also: https://lab.civicrm.org/dev/core/issues/284

Before (Behavior in version <=`5.3`)
----------------------------------------

On systems with memory-backed caches, `flushCache()` had an aggressive
cascading side-effect where several named caches (`settings`, etc) were also
flushed.

On systems with a default configuration (SQL+ArrayCache), `flushCache()` had a
very limited cascading effect -- it *only cleared the in-process ArrayCache*.
The bulk of the cache content was preserved in SQL.

Before (Behavior in version ~= `5.4.alpha`)
----------------------------------------

To simulate the cascading effect, `flushCache()` explicitly flushes a
half-dozen individual caches.  (These half-dozen are chosen to match the old
cascade list and exclude some new things which would problematic.)

On systems with memory-backed caches, this reproduces the aggressive cascading
effect.

On systems with a default configuration (SQL+ArrayCache), this amplifies the
flushing -- because it also destroys the underlying SQL caches.

This has the side-effect of significantly degrading performance of the test
suite.

After (Behavior with patch)
----------------------------------------

`CRM_Utils_System::flushCache` calls `CRM_Utils_Cache::singleton()->flush()`.

To simulate the cascading effect, `flushCache()` explicitly flushes a
half-dozen individual caches...  *but only on memory-backed* systems.

On systems with memory-backed caches, this reproduces the aggressive cascading
effect.

On systems with a default configuration (SQL+ArrayCache), this is closer to the
old behavior.  The bulk of the cache remains available in SQL.

Based on local spot-checking, this restores performance of the test suite.

Comments
----------------------------------------

Deep down, I don't really believe the cascading effect is a good thing.  At
some point, I'd rather just remove these bits.  But in absence of a crystal
ball to predict the side-effects of that, I think it's good to find a better
approximation of the old behavior.

CRM/Utils/System.php

index e88076c21735a520bf9440825df4d50f55421673..fb5bb879ea4e173673bc3672a59e41d4a1f95651 100644 (file)
@@ -1417,7 +1417,14 @@ class CRM_Utils_System {
     // flush out all cache entries so we can reload new data
     // a bit aggressive, but livable for now
     CRM_Utils_Cache::singleton()->flush();
-    if (Civi\Core\Container::isContainerBooted()) {
+
+    // Traditionally, systems running on memory-backed caches were quite
+    // zealous about destroying *all* memory-backed caches during a flush().
+    // These flushes simulate that legacy behavior. However, they should probably
+    // be removed at some point.
+    $localDrivers = ['CRM_Utils_Cache_Arraycache', 'CRM_Utils_Cache_NoCache'];
+    if (Civi\Core\Container::isContainerBooted()
+      && !in_array(get_class(CRM_Utils_Cache::singleton()), $localDrivers)) {
       Civi::cache('settings')->flush();
       Civi::cache('js_strings')->flush();
       Civi::cache('community_messages')->flush();