Ignore refs/multi-site/version on global-refdb in replication filter When I509dd7075b0 stopped updating the SHA1 for refs/multi-site/version in global-refdb in this stable-3.4 branch, it did not take into consideration that existing setups may have plenty of refs/multi-site/version already stored on them. Stopping the update of those refs on the global-refdb had a negative impact on the consistency of the replication of refs/multi-site/version across the multi-site clusters, causing false alarms of replication lags. Consider the refs/multi-site/version on global-refdb as non-existent and skip altogether the associated checks if the associated local refs were already up-to-date. This change effectively ignores weather the local refs/multi-site/version is up-to-date or not and always fetches from the remote repository ref. Change-Id: I8b938675f54d18542e34b735ff1e6d63f2ab2a31
diff --git a/src/main/java/com/googlesource/gerrit/plugins/multisite/validation/MultisiteReplicationFetchFilter.java b/src/main/java/com/googlesource/gerrit/plugins/multisite/validation/MultisiteReplicationFetchFilter.java index 21d4073..d851420 100644 --- a/src/main/java/com/googlesource/gerrit/plugins/multisite/validation/MultisiteReplicationFetchFilter.java +++ b/src/main/java/com/googlesource/gerrit/plugins/multisite/validation/MultisiteReplicationFetchFilter.java
@@ -14,6 +14,7 @@ package com.googlesource.gerrit.plugins.multisite.validation; +import static com.googlesource.gerrit.plugins.multisite.validation.ProjectVersionRefUpdate.MULTI_SITE_VERSIONING_REF; import static com.googlesource.gerrit.plugins.replication.pull.PullReplicationLogger.repLog; import com.gerritforge.gerrit.globalrefdb.GlobalRefDbLockException; @@ -64,6 +65,9 @@ .filter(ref -> !hasBeenRemovedFromGlobalRefDb(projectName, ref)) .filter( ref -> { + if (shouldNotBeTrackedAnymoreOnGlobalRefDb(ref)) { + return true; + } Optional<ObjectId> localRefOid = getLocalSha1IfEqualsToExistingGlobalRefDb( repository, projectName, refDb, ref, true); @@ -87,6 +91,19 @@ } } + /* + * Since ac43a5f94c773c9db7a73d44035961d69d13fa53 the 'refs/multi-site/version' is + * not updated anymore on the global-refdb; however, the values stored already + * on the global-refdb could get in the way and prevent replication from happening + * as expected. + * + * Exclude the 'refs/multi-site/version' from local vs. global refdb checking + * pretending that the global-refdb for that ref did not exist. + */ + private boolean shouldNotBeTrackedAnymoreOnGlobalRefDb(String ref) { + return MULTI_SITE_VERSIONING_REF.equals(ref); + } + /* If the ref to fetch has been set to all zeros on the global-refdb, it means * that whatever is the situation locally, we do not need to fetch it: * - If the remote still has it, fetching it will be useless because the global
diff --git a/src/test/java/com/googlesource/gerrit/plugins/multisite/validation/MultisiteReplicationFetchFilterTest.java b/src/test/java/com/googlesource/gerrit/plugins/multisite/validation/MultisiteReplicationFetchFilterTest.java index 9a7a3b3..e09f6f6 100644 --- a/src/test/java/com/googlesource/gerrit/plugins/multisite/validation/MultisiteReplicationFetchFilterTest.java +++ b/src/test/java/com/googlesource/gerrit/plugins/multisite/validation/MultisiteReplicationFetchFilterTest.java
@@ -170,6 +170,24 @@ } @Test + public void shouldNotFilterOutWhenRefsMultisiteVersionIsPresentInSharedRefDb() throws Exception { + String refsMultisiteVersionRef = ProjectVersionRefUpdate.MULTI_SITE_VERSIONING_REF; + RevCommit multiSiteVersionRef = newRef(refsMultisiteVersionRef); + + doReturn(Optional.of(multiSiteVersionRef.getId().getName())) + .when(sharedRefDatabaseMock) + .get(eq(projectName), eq(refsMultisiteVersionRef), eq(String.class)); + + Set<String> refsToFetch = Set.of(refsMultisiteVersionRef); + + MultisiteReplicationFetchFilter fetchFilter = + new MultisiteReplicationFetchFilter(sharedRefDatabaseMock, gitRepositoryManager, config); + Set<String> filteredRefsToFetch = fetchFilter.filter(project, refsToFetch); + + assertThat(filteredRefsToFetch).hasSize(1); + } + + @Test public void shouldFilterOutWhenRefIsDeletedInTheSharedRefDb() throws Exception { String temporaryOutdated = "refs/heads/temporaryOutdated"; newRef(temporaryOutdated);