(dev/core#174) CRM_Utils_Cache - Always use a prefix. Standardize delimiter.
"Prefixes" are a way to have one cache-server (e.g. one instance of redis or memcached)
which stores several different data-sets. `CRM_Utils_Cache` uses prefixes in a couple ways:
* (1) General site prefix (controlled via `civicrm.settings.php`)
* (1a) If you have a single-site deployment, then the general prefix is blank.
* (1b) If you have a multi-site deployment, then each site should use a different prefix (`mysite_1`, `mysite_2`, etc).
* (2) Within a given deployment, prefixes may indicate different logical data-sets.
* (2a) `Civi::cache()` or `Civi::cache('default')` or `CRM_Utils_Cache::singleton()` are the `default` data-set.
* (2b) `CRM_Utils_Cache::create()` can instantiate new, special-purpose
data-sets. For example, this is used for `Civi::cache('js_strings')`.
This patch addresses two issues:
* (Functional) Flushing the 'default' cache would likely flush all other caches
because the 'default' cache didn't have a distinctive prefix. (This was observed Redis. Theoretically,
the bug would apply to some-but-not-all cache backends.)
* (Aesthetic) The full cache paths don't look consistent because they don't have a standard dlimiter.
To fully understand, it helps to see example cache keys produced in a few
configurations before and after the patch.
See also: https://lab.civicrm.org/dev/core/issues/174
Before
-----------------------------
| |Deployment Type|Logical Cache |Combined Cache Prefix |Example Cache Item (`foobar`)|
|-|-|---------------|-------|-----------------|
|1a,2a|Single-site|`default` |(empty-string)|`foobar`|
|1a,2b|Single-site| `js_strings` |`_js_strings`|`_js_stringsfoobar`|
|1b,2a|Multi-site |`default` |`mysite_1_`|`mysite_1_foobar`|
|1b,2b|Multi-site |`js_strings` |`mysite_1_js_strings`|`mysite_1_js_stringsfoobar`|
* If you have a single-site deployment and try to flush `default`, you
inadvertently flush `js_strings` because everything matches the empty-string prefix.
* If you have a multi-site deployment and try to flush `default`, you
inadvertently flush `js_strings` because the prefix overlaps.
* The three parts of the key (deployment ID, logical cache, and cache item) are not necessarily separated.
After
-----------------------------
| |Deployment Type|Logical Cache |Combined Cache Prefix |Example Cache Item (`foobar`)|
|-|-|---------------|-------|-----------------|
|1a,2a|Single-site|`default` |`/default/`|`/default/foobar`|
|1a,2b|Single-site|`js_strings` |`/js_strings/`|`/js_strings/foobar`|
|1b,2a|Multi-site |`default` |`mysite_1/default/`|`mysite_1/default/foobar`|
|1b,2b|Multi-site |`js_strings` |`mysite_1/js_strings/`|`mysite_1/js_strings/foobar`|
* If you have a single-site deployment and try to flush `default`, you
only flush `default` because the prefixes are distinct.
* If you have a multi-site deployment and try to flush `default`, you
only flush `default` because the prefixes are distinct.
* The three parts of the key (deployment ID, logical cache, and cache item) are always separated by `/`.
Comments
--------
When developing this patch, I found it helpful to:
* Enable Redis driver
* Open `redis-cli` and view the list of cache items with `keys *`.