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

Reply via email to