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);