From: Tim Otten Date: Sat, 12 Sep 2015 03:36:44 +0000 (-0700) Subject: CRM_Utils_Cache::create - Use factory function X-Git-Url: https://vcs.fsf.org/?a=commitdiff_plain;h=a47044042eb3aee21ca20a7828a0cf5a09399614;p=civicrm-core.git CRM_Utils_Cache::create - Use factory function Low-level tools like GenCode may run without access to a database. When we try to use caching in central code, the cache-accesses are prone to crashing. The problem -- in this environment, we shouldn't even try to use databse for caching. `CRM_Utils_Cache::create()` will attempt to create the best cache it can, depending on what services are available. --- diff --git a/CRM/Core/BAO/Setting.php b/CRM/Core/BAO/Setting.php index a9688fc9ac..e249aeca52 100644 --- a/CRM/Core/BAO/Setting.php +++ b/CRM/Core/BAO/Setting.php @@ -44,6 +44,7 @@ class CRM_Core_BAO_Setting extends CRM_Core_DAO_Setting { * Various predefined settings that have been migrated to the setting table. */ const + ALL = 'all', ADDRESS_STANDARDIZATION_PREFERENCES_NAME = 'Address Standardization Preferences', CAMPAIGN_PREFERENCES_NAME = 'Campaign Preferences', DEVELOPER_PREFERENCES_NAME = 'Developer Preferences', @@ -633,22 +634,25 @@ class CRM_Core_BAO_Setting extends CRM_Core_DAO_Setting { $domainID = NULL, $profile = NULL ) { - $cacheString = 'settingsMetadata_' . $domainID . '_' . $profile; + $cache = Civi::cache('settings'); + + $cacheString = 'settingsMetadata_' . $domainID . '_' . $profile . '_' . $componentID; foreach ($filters as $filterField => $filterString) { $cacheString .= "_{$filterField}_{$filterString}"; } $cached = 1; // the caching into 'All' seems to be a duplicate of caching to // settingsMetadata__ - I think the reason was to cache all settings as defined & then those altered by a hook - $settingsMetadata = CRM_Core_BAO_Cache::getItem('CiviCRM setting Specs', $cacheString, $componentID); + $settingsMetadata = $cache->get($cacheString); + if ($settingsMetadata === NULL) { - $settingsMetadata = CRM_Core_BAO_Cache::getItem('CiviCRM setting Spec', 'All', $componentID); + $settingsMetadata = $cache->get(self::ALL); if (empty($settingsMetadata)) { global $civicrm_root; $metaDataFolders = array($civicrm_root . '/settings'); CRM_Utils_Hook::alterSettingsFolders($metaDataFolders); $settingsMetadata = self::loadSettingsMetaDataFolders($metaDataFolders); - CRM_Core_BAO_Cache::setItem($settingsMetadata, 'CiviCRM setting Spec', 'All', $componentID); + $cache->set(self::ALL, $settingsMetadata); } $cached = 0; } @@ -660,12 +664,7 @@ class CRM_Core_BAO_Setting extends CRM_Core_DAO_Setting { // this is a bit 'heavy' if you are using hooks but this function // is expected to only be called during setting administration // it should not be called by 'getvalue' or 'getitem - CRM_Core_BAO_Cache::setItem( - $settingsMetadata, - 'CiviCRM setting Specs', - $cacheString, - $componentID - ); + $cache->set($cacheString, $settingsMetadata); } return $settingsMetadata; @@ -700,7 +699,7 @@ class CRM_Core_BAO_Setting extends CRM_Core_DAO_Setting { $settings = include $file; $settingMetaData = array_merge($settingMetaData, $settings); } - CRM_Core_BAO_Cache::setItem($settingMetaData, 'CiviCRM setting Spec', 'All'); + Civi::cache('settings')->set(self::ALL, $settingMetaData); return $settingMetaData; } diff --git a/CRM/Core/CommunityMessages.php b/CRM/Core/CommunityMessages.php index 908bf362f0..c99c945d77 100644 --- a/CRM/Core/CommunityMessages.php +++ b/CRM/Core/CommunityMessages.php @@ -60,10 +60,7 @@ class CRM_Core_CommunityMessages { */ public static function create() { return new CRM_Core_CommunityMessages( - new CRM_Utils_Cache_SqlGroup(array( - 'group' => 'community-messages', - 'prefetch' => FALSE, - )), + Civi::cache('community_messages'), CRM_Utils_HttpClient::singleton() ); } diff --git a/CRM/Core/Resources.php b/CRM/Core/Resources.php index 7d0e3649e4..f2bb53a18f 100644 --- a/CRM/Core/Resources.php +++ b/CRM/Core/Resources.php @@ -111,10 +111,7 @@ class CRM_Core_Resources { } if (self::$_singleton === NULL) { $sys = CRM_Extension_System::singleton(); - $cache = new CRM_Utils_Cache_SqlGroup(array( - 'group' => 'js-strings', - 'prefetch' => FALSE, - )); + $cache = Civi::cache('js_strings'); self::$_singleton = new CRM_Core_Resources( $sys->getMapper(), $cache, diff --git a/CRM/Cxn/CiviCxnHttp.php b/CRM/Cxn/CiviCxnHttp.php index c64e79be60..d1b5e7f48b 100644 --- a/CRM/Cxn/CiviCxnHttp.php +++ b/CRM/Cxn/CiviCxnHttp.php @@ -22,17 +22,11 @@ class CRM_Cxn_CiviCxnHttp extends \Civi\Cxn\Rpc\Http\PhpHttp { */ public static function singleton($fresh = FALSE) { if (self::$singleton === NULL || $fresh) { - $config = CRM_Core_Config::singleton(); - - if ($config->debug) { - $cache = new CRM_Utils_Cache_Arraycache(array()); - } - else { - $cache = new CRM_Utils_Cache_SqlGroup(array( - 'group' => 'CiviCxnHttp', - 'prefetch' => FALSE, - )); - } + $cache = CRM_Utils_Cache::create(array( + 'name' => 'CiviCxnHttp', + 'type' => Civi::settings()->get('debug_enabled') ? 'ArrayCache' : array('SqlGroup', 'ArrayCache'), + 'prefetch' => FALSE, + )); self::$singleton = new CRM_Cxn_CiviCxnHttp($cache); } diff --git a/CRM/Extension/System.php b/CRM/Extension/System.php index e453bc167f..a04d63cb7c 100644 --- a/CRM/Extension/System.php +++ b/CRM/Extension/System.php @@ -240,16 +240,13 @@ class CRM_Extension_System { */ public function getCache() { if ($this->cache === NULL) { - if (defined('CIVICRM_DSN')) { - $cacheGroup = md5(serialize(array('ext', $this->parameters))); - $this->cache = new CRM_Utils_Cache_SqlGroup(array( - 'group' => $cacheGroup, - 'prefetch' => TRUE, - )); - } - else { - $this->cache = new CRM_Utils_Cache_ArrayCache(array()); - } + $cacheGroup = md5(serialize(array('ext', $this->parameters))); + // Extension system starts before container. Manage our own cache. + $this->cache = CRM_Utils_Cache::create(array( + 'name' => $cacheGroup, + 'type' => array('SqlGroup', 'ArrayCache'), + 'prefetch' => TRUE, + )); } return $this->cache; } diff --git a/CRM/Utils/Cache.php b/CRM/Utils/Cache.php index ef4afa27d0..5caa450dbe 100644 --- a/CRM/Utils/Cache.php +++ b/CRM/Utils/Cache.php @@ -162,4 +162,43 @@ class CRM_Utils_Cache { return $defaults; } + /** + * Create a new, named, limited-use cache. + * + * This is a factory function. Generally, you should use Civi::cache($name) + * to locate managed cached instance. + * + * @param array $params + * Array with keys: + * - name: string, unique symbolic name. + * - type: array|string, list of acceptable cache types, in order of preference. + * - prefetch: bool, whether to prefetch all data in cache (if possible). + * @return CRM_Utils_Cache_Interface + * @throws CRM_Core_Exception + * @see Civi::cache() + */ + public static function create($params = array()) { + $types = (array) $params['type']; + + foreach ($types as $type) { + switch ($type) { + case 'SqlGroup': + if (defined('CIVICRM_DSN') && CIVICRM_DSN) { + return new CRM_Utils_Cache_SqlGroup(array( + 'group' => $params['name'], + 'prefetch' => CRM_Utils_Array::value('prefetch', $params, FALSE), + )); + } + break; + + case 'Arraycache': + case 'ArrayCache': + return new CRM_Utils_Cache_ArrayCache(array()); + + } + } + + throw new CRM_Core_Exception("Failed to instantiate cache. No supported cache type found. " . print_r($params, 1)); + } + } diff --git a/Civi/Core/Container.php b/Civi/Core/Container.php index d281b06eaa..e1d0132e02 100644 --- a/Civi/Core/Container.php +++ b/Civi/Core/Container.php @@ -174,12 +174,17 @@ class Container { $container->setDefinition('psr_log', new Definition('CRM_Core_Error_Log', array())); - $container->setDefinition('cache.settings', new Definition( - 'CRM_Utils_Cache_SqlGroup', - array( - array('group' => 'Settings', 'prefetch' => 0), - ) - )); + foreach (array('settings', 'js_strings', 'community_messages') as $cacheName) { + $container->setDefinition("cache.{$cacheName}", new Definition( + 'CRM_Utils_Cache_Interface', + array( + array( + 'name' => $cacheName, + 'type' => array('SqlGroup', 'ArrayCache'), + ), + ) + ))->setFactoryClass('CRM_Utils_Cache')->setFactoryMethod('create'); + } $container->setDefinition('settings_manager', new Definition( 'Civi\Core\SettingsManager',