Eileen has uploaded a new change for review. ( https://gerrit.wikimedia.org/r/377386 )
Change subject: CRM-21109 only clear caches once on cli script, consolidate code ...................................................................... CRM-21109 only clear caches once on cli script, consolidate code This is a combination of the commits in https://github.com/civicrm/civicrm-core/pull/10943 Bringing this in does not make any actual change for us. However, it makes it easier for us to play with the following options 1) setting cache mode to FALSE on a per process basis. Currently there are statics to try to ensure that caches are flushed only once per process, but without this the add to group & remove from group functions bypass them. From a script CRM_Core_Config::setPermitCacheFlushMode(FALSE); would prevent cache flushing in the session for group_contact_cache & acl caches until the script ends or it is retoggled. Also acl caches were not previously subject to the statics. 2)We would consider flushing caches by cron rather than during script runtime. There is a setting for that & we could extend to cover acl cache. Flushing by cron permits (optionally) the use of TRUNCATE - which appears to be faster for everyone in the world but us :-) Change-Id: Ib790939421d3b7ce5d2e258154a8015b8652234f --- M CRM/ACL/BAO/Cache.php M CRM/Contact/BAO/Contact.php M CRM/Contact/BAO/Contact/Utils.php M CRM/Contact/BAO/GroupContact.php M CRM/Contact/BAO/GroupContactCache.php M CRM/Contact/Form/Merge.php M CRM/Contact/Import/Form/Preview.php M CRM/Contact/Import/Parser/Contact.php M CRM/Core/Config.php M CRM/Dedupe/Merger.php M bin/cli.class.php 11 files changed, 57 insertions(+), 59 deletions(-) git pull ssh://gerrit.wikimedia.org:29418/wikimedia/fundraising/crm/civicrm refs/changes/86/377386/1 diff --git a/CRM/ACL/BAO/Cache.php b/CRM/ACL/BAO/Cache.php index e1e989c..d6f156d 100644 --- a/CRM/ACL/BAO/Cache.php +++ b/CRM/ACL/BAO/Cache.php @@ -142,6 +142,9 @@ * Deletes all the cache entries. */ public static function resetCache() { + if (!CRM_Core_Config::isPermitCacheFlushMode()) { + return; + } // reset any static caching self::$_cache = NULL; diff --git a/CRM/Contact/BAO/Contact.php b/CRM/Contact/BAO/Contact.php index 0460b22..f9edbba 100644 --- a/CRM/Contact/BAO/Contact.php +++ b/CRM/Contact/BAO/Contact.php @@ -356,9 +356,7 @@ //add website CRM_Core_BAO_Website::create($params['website'], $contact->id, $skipDelete); - //get userID from session - $session = CRM_Core_Session::singleton(); - $userID = $session->get('userID'); + $userID = CRM_Core_Session::singleton()->get('userID'); // add notes if (!empty($params['note'])) { if (is_array($params['note'])) { @@ -432,13 +430,7 @@ 'name' ); - if (!$config->doNotResetCache) { - // Note: doNotResetCache flag is currently set by import contact process and merging, - // since resetting and - // rebuilding cache could be expensive (for many contacts). We might come out with better - // approach in future. - CRM_Contact_BAO_Contact_Utils::clearContactCaches($contact->id); - } + CRM_Contact_BAO_Contact_Utils::clearContactCaches(); if ($invokeHooks) { if ($isEdit) { diff --git a/CRM/Contact/BAO/Contact/Utils.php b/CRM/Contact/BAO/Contact/Utils.php index 9cbb44d..2ac9af4 100644 --- a/CRM/Contact/BAO/Contact/Utils.php +++ b/CRM/Contact/BAO/Contact/Utils.php @@ -897,18 +897,21 @@ * caches, but are backing off from this with every release. Compromise between ease of coding versus * performance versus being accurate at that very instant * - * @param $contactID - * The contactID that was edited / deleted. + * @param bool $isEmptyPrevNextTable + * Should the civicrm_prev_next table be cleared of any contact entries. + * This is currently done from import but not other places and would + * likely affect user experience in unexpected ways. Existing behaviour retained + * ... reluctantly. */ - public static function clearContactCaches($contactID = NULL) { - // clear acl cache if any. - CRM_ACL_BAO_Cache::resetCache(); - - if (empty($contactID)) { - // also clear prev/next dedupe cache - if no contactID passed in + public static function clearContactCaches($isEmptyPrevNextTable = FALSE) { + if (!CRM_Core_Config::isPermitCacheFlushMode()) { + return; + } + if ($isEmptyPrevNextTable) { CRM_Core_BAO_PrevNextCache::deleteItem(); } - + // clear acl cache if any. + CRM_ACL_BAO_Cache::resetCache(); CRM_Contact_BAO_GroupContactCache::opportunisticCacheFlush(); } diff --git a/CRM/Contact/BAO/GroupContact.php b/CRM/Contact/BAO/GroupContact.php index 8833d19..73bf59b 100644 --- a/CRM/Contact/BAO/GroupContact.php +++ b/CRM/Contact/BAO/GroupContact.php @@ -143,15 +143,7 @@ list($numContactsAdded, $numContactsNotAdded) = self::bulkAddContactsToGroup($contactIds, $groupId, $method, $status, $tracking); - // also reset the acl cache - $config = CRM_Core_Config::singleton(); - if (!$config->doNotResetCache) { - CRM_ACL_BAO_Cache::resetCache(); - } - - // reset the group contact cache for all group(s) - // if this group is being used as a smart group - CRM_Contact_BAO_GroupContactCache::opportunisticCacheFlush(); + CRM_Contact_BAO_Contact_Utils::clearContactCaches(); CRM_Utils_Hook::post('create', 'GroupContact', $groupId, $contactIds); @@ -245,21 +237,7 @@ } } - // also reset the acl cache - $config = CRM_Core_Config::singleton(); - if (!$config->doNotResetCache) { - CRM_ACL_BAO_Cache::resetCache(); - } - - // reset the group contact cache for all group(s) - // if this group is being used as a smart group - // @todo consider what to do here - it feels like we should either - // 1) just invalidate the specific group's cache(& perhaps any parents) & let cron do it's thing or - // possibly clear this specific groups cache, or just call opportunisticCacheFlush() - which would have the - // same effect as the remove call. The reservation about that is that it is no more aggressive for the group that - // we know is altered than for all the others, or perhaps, more the point with it's parents & groups that use it in - // their criteria. - CRM_Contact_BAO_GroupContactCache::remove(); + CRM_Contact_BAO_Contact_Utils::clearContactCaches(); CRM_Utils_Hook::post($op, 'GroupContact', $groupId, $contactIds); diff --git a/CRM/Contact/BAO/GroupContactCache.php b/CRM/Contact/BAO/GroupContactCache.php index 8875275..9abc853 100644 --- a/CRM/Contact/BAO/GroupContactCache.php +++ b/CRM/Contact/BAO/GroupContactCache.php @@ -297,16 +297,18 @@ * In fact it turned out there is little overlap between the code when group is passed in * and group is not so it makes more sense as separate functions. * - * @todo remove last call to this function from outside the class then make function protected, - * enforce groupID as an array & remove non group handling. + * @todo enforce groupID as an array & remove non group handling. + * Use flushCaches when no group id provided. * * @param int $groupIDs * the groupID to delete cache entries, NULL for all groups. * @param bool $onceOnly * run the function exactly once for all groups. */ - public static function remove($groupIDs = NULL, $onceOnly = TRUE) { - static $invoked = FALSE; + protected static function remove($groupIDs = NULL, $onceOnly = TRUE) { + if (!isset(Civi::$statics[__CLASS__]['remove_invoked'])) { + Civi::$statics[__CLASS__] = array('remove_invoked' => FALSE); + } // typically this needs to happy only once per instance // this is especially TRUE in import, where we don't need @@ -315,14 +317,14 @@ // i.e. cache is reset for all groups if ( $onceOnly && - $invoked && + Civi::$statics[__CLASS__]['remove_invoked'] && $groupIDs == NULL ) { return; } if ($groupIDs == NULL) { - $invoked = TRUE; + Civi::$statics[__CLASS__]['remove_invoked'] = TRUE; } elseif (is_array($groupIDs)) { foreach ($groupIDs as $gid) { @@ -479,7 +481,7 @@ * @throws \CRM_Core_Exception */ protected static function getLockForRefresh() { - if (!isset(Civi::$statics[__CLASS__])) { + if (!isset(Civi::$statics[__CLASS__]['is_refresh_init'])) { Civi::$statics[__CLASS__] = array('is_refresh_init' => FALSE); } diff --git a/CRM/Contact/Form/Merge.php b/CRM/Contact/Form/Merge.php index 1be1904..146b153 100644 --- a/CRM/Contact/Form/Merge.php +++ b/CRM/Contact/Form/Merge.php @@ -115,7 +115,7 @@ // get user info of main contact. $config = CRM_Core_Config::singleton(); - $config->doNotResetCache = 1; + CRM_Core_Config::setPermitCacheFlushMode(FALSE); $mainUfId = CRM_Core_BAO_UFMatch::getUFId($this->_cid); $mainUser = NULL; diff --git a/CRM/Contact/Import/Form/Preview.php b/CRM/Contact/Import/Form/Preview.php index 26c8e14..ca8aff5 100644 --- a/CRM/Contact/Import/Form/Preview.php +++ b/CRM/Contact/Import/Form/Preview.php @@ -306,7 +306,7 @@ // Clear all caches, forcing any searches to recheck the ACLs or group membership as the import // may have changed it. - CRM_Contact_BAO_Contact_Utils::clearContactCaches(); + CRM_Contact_BAO_Contact_Utils::clearContactCaches(TRUE); // add all the necessary variables to the form $importJob->setFormVariables($this); diff --git a/CRM/Contact/Import/Parser/Contact.php b/CRM/Contact/Import/Parser/Contact.php index dd3807d..5e8253a 100644 --- a/CRM/Contact/Import/Parser/Contact.php +++ b/CRM/Contact/Import/Parser/Contact.php @@ -1691,11 +1691,10 @@ $this->formatParams($formatted, $onDuplicate, (int) $contactId); } - // pass doNotResetCache flag since resetting and rebuilding cache could be expensive. - $config = CRM_Core_Config::singleton(); - $config->doNotResetCache = 1; + // Resetting and rebuilding cache could be expensive. + CRM_Core_Config::setPermitCacheFlushMode(FALSE); $cid = CRM_Contact_BAO_Contact::createProfileContact($formatted, $contactFields, $contactId, NULL, NULL, $formatted['contact_type']); - $config->doNotResetCache = 0; + CRM_Core_Config::setPermitCacheFlushMode(TRUE); $contact = array( 'contact_id' => $cid, diff --git a/CRM/Core/Config.php b/CRM/Core/Config.php index f8ef270..93e2380 100644 --- a/CRM/Core/Config.php +++ b/CRM/Core/Config.php @@ -546,4 +546,24 @@ Civi::settings()->set('installed', 1); } + /** + * Is the system permitted to flush caches at the moment. + */ + static public function isPermitCacheFlushMode() { + return !CRM_Core_Config::singleton()->doNotResetCache; + } + + /** + * Set cache clearing to enabled or disabled. + * + * This might be enabled at the start of a long running process + * such as an import in order to delay clearing caches until the end. + * + * @param bool $enabled + * If true then caches can be cleared at this time. + */ + static public function setPermitCacheFlushMode($enabled) { + CRM_Core_Config::singleton()->doNotResetCache = $enabled ? 0 : 1; + } + } diff --git a/CRM/Dedupe/Merger.php b/CRM/Dedupe/Merger.php index 2c59e88..96ff298 100644 --- a/CRM/Dedupe/Merger.php +++ b/CRM/Dedupe/Merger.php @@ -764,9 +764,7 @@ $resultStats = array('merged' => array(), 'skipped' => array()); // we don't want dupe caching to get reset after every-merge, and therefore set the - // doNotResetCache flag - $config = CRM_Core_Config::singleton(); - $config->doNotResetCache = 1; + CRM_Core_Config::setPermitCacheFlushMode(FALSE); $deletedContacts = array(); while (!empty($dupePairs)) { diff --git a/bin/cli.class.php b/bin/cli.class.php index dbcc5e9..11b4366 100644 --- a/bin/cli.class.php +++ b/bin/cli.class.php @@ -99,6 +99,7 @@ public function callApi() { require_once 'api/api.php'; + CRM_Core_Config::setPermitCacheFlushMode(FALSE); // CRM-9822 -'execute' action always goes thru Job api and always writes to log if ($this->_action != 'execute' && $this->_joblog) { require_once 'CRM/Core/JobManager.php'; @@ -111,6 +112,8 @@ $this->_params['auth'] = FALSE; $result = civicrm_api($this->_entity, $this->_action, $this->_params); } + CRM_Core_Config::setPermitCacheFlushMode(TRUE); + CRM_Contact_BAO_Contact_Utils::clearContactCaches(); if (!empty($result['is_error'])) { $this->_log($result['error_message']); -- To view, visit https://gerrit.wikimedia.org/r/377386 To unsubscribe, visit https://gerrit.wikimedia.org/r/settings Gerrit-MessageType: newchange Gerrit-Change-Id: Ib790939421d3b7ce5d2e258154a8015b8652234f Gerrit-PatchSet: 1 Gerrit-Project: wikimedia/fundraising/crm/civicrm Gerrit-Branch: master Gerrit-Owner: Eileen <emcnaugh...@wikimedia.org> _______________________________________________ MediaWiki-commits mailing list MediaWiki-commits@lists.wikimedia.org https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits