1. CRM_Utils_Cache::create()
When looking through the list of cache drivers, you see options like Memcache
, Memcached
, and Redis
. Generally there's little reason why a deployment would use all three -- rather, the typical question this:
- Do we have any kind of high-speed/shared/memory-based cache? If so, use it.
- Do we have any kind of SQL-backed cache? If so, use it.
- Otherwise, use an ephemeral
array()
(for the duration each request)
In v4.7, CRM_Utils_Cache::create()
is a factory function which accepts an ordered list of drivers, and it picks the first one that's usable, e.g.
$myCache = CRM_Utils_Cache::create(array(
'name' => 'somethingsomething',
'type' => array('*memory*', 'SqlGroup', 'ArrayCache'),
));
This aims to address the typical use-case by making it unnecessary for the admin to configure anything extra for your specific extension.
Your extension would need to retain a copy of that cache object, e.g.
function myextension_cache() {
if (!isset(Civi::$statics['myextension_cache'])) {
Civi::$statics['myextension_cache'] = CRM_Utils_Cache::create(array(
'name' => 'somethingsomething',
'type' => array('*memory*', 'SqlGroup', 'ArrayCache'),
));
}
return Civi::$statics['myextension_cache'];
}
I believe this answers the typical requirement/issue when someone wants to configure the extension's cache, but it doesn't literally answer the question...
2. Named services and caching
The Symfony service container is a general-purpose tool for naming and tracking a bunch of objects -- cache services, database services, entity-repositories, etc. Rather than have a hundred functions like myextension_cache()
which hard-code the factory, we put all the factories together in the container. This pattern improves our leverage; in principle, you can expose the container to different processes, e.g.
- Reading multiple YAML/XML files to configure the container
- Allowing extensions/hooks to alter the container
- Allowing site admins to alter the container
- Allowing dev-tools and admin-tools to inspect the container
For this reason, new caches in core tend to be created through the container, e.g.
However, at this point, the container in Civi needs improvement. For example, you can alter the container via hook_civicrm_container
, but there's no YAML/XML/annotation mechanism for updating the container, and there's no mechanism for site-admins to modify services via config file (civicrm.settings.php
).
The long-term goal is to shift more service-management into a container so that questions like "How does a site admin customize service X?" have a categorical answer. Improving the container is very much patch-welcome.