dev/core#1862 Skip cache tables during merge, rely on cache management processes
authoreileen <emcnaughton@wikimedia.org>
Mon, 13 Jul 2020 01:15:28 +0000 (13:15 +1200)
committereileen <emcnaughton@wikimedia.org>
Mon, 13 Jul 2020 05:24:03 +0000 (17:24 +1200)
We later call Contact.create on both contacts so that should manage the caches for this update 'as well as for any other update'
and solve the bug + reduce locking queries

CRM/Dedupe/Merger.php
tests/phpunit/CRM/Dedupe/MergerTest.php
tests/phpunit/api/v3/JobTest.php

index a6213effc9c7b6ab6388dc670e3d442e63479be3..9bdc157ac1c4a72a673d9454adf2fc5fe9954705 100644 (file)
@@ -225,6 +225,11 @@ class CRM_Dedupe_Merger {
     }
 
     $contactReferences = $coreReferences = CRM_Core_DAO::getReferencesToContactTable();
+    foreach (['civicrm_group_contact_cache', 'civicrm_acl_cache', 'civicrm_acl_contact_cache'] as $tableName) {
+      // Don't merge cache tables. These should be otherwise cleared at some point in the dedupe
+      // but they are prone to locking to let's not touch during the dedupe.
+      unset($contactReferences[$tableName], $coreReferences[$tableName]);
+    }
 
     CRM_Utils_Hook::merge('cidRefs', $contactReferences);
     if ($contactReferences !== $coreReferences) {
index e796173fa4b7641c8366630b2e4cd06349e889e2..8f4bf06043473a7d0e2dd1f3cda7089ec9ef60d0 100644 (file)
@@ -285,8 +285,10 @@ class CRM_Dedupe_MergerTest extends CiviUnitTestCase {
    */
   public function testGetCidRefs() {
     $this->entityCustomGroupWithSingleFieldCreate(__FUNCTION__, 'Contacts');
-    $this->assertEquals($this->getStaticCIDRefs(), CRM_Dedupe_Merger::cidRefs());
-    $this->assertEquals($this->getCalculatedCIDRefs(), CRM_Dedupe_Merger::cidRefs());
+    // These are deliberately unset.
+    $unsetRefs = array_fill_keys(['civicrm_group_contact_cache', 'civicrm_acl_cache', 'civicrm_acl_contact_cache'], 1);
+    $this->assertEquals(array_diff_key($this->getStaticCIDRefs(), $unsetRefs), CRM_Dedupe_Merger::cidRefs());
+    $this->assertEquals(array_diff_key($this->getCalculatedCIDRefs(), $unsetRefs), CRM_Dedupe_Merger::cidRefs());
   }
 
   /**
index 444714204ab93936985eec1c5b06a698b38cefa6..f6a9bfb27c2b705da9cbbf04397303568babbab7 100644 (file)
@@ -573,11 +573,27 @@ class api_v3_JobTest extends CiviUnitTestCase {
     foreach ($groupResult['values'] as $groupValues) {
       $this->assertEquals($contactID, $groupValues['contact_id']);
       $this->assertEquals('Added', $groupValues['status']);
-      $this->assertTrue(in_array($groupValues['group_id'], $expectedGroups));
+      $this->assertContains($groupValues['group_id'], $expectedGroups);
 
     }
   }
 
+  /**
+   * Test that we handle cache entries without clashes.
+   */
+  public function testMergeCaches() {
+    $contactID = $this->individualCreate();
+    $contact2ID = $this->individualCreate();
+    $groupID = $this->groupCreate();
+    $this->callAPISuccess('GroupContact', 'create', ['group_id' => $groupID, 'contact_id' => $contactID]);
+    $this->callAPISuccess('GroupContact', 'create', ['group_id' => $groupID, 'contact_id' => $contact2ID]);
+    CRM_Core_DAO::executeQuery("INSERT INTO civicrm_group_contact_cache(group_id, contact_id) VALUES
+      ($groupID, $contactID),
+      ($groupID, $contact2ID)
+    ");
+    $this->callAPISuccess('Job', 'process_batch_merge', ['mode' => 'safe']);
+  }
+
   /**
    * Test the decisions made for addresses when merging.
    *