Provide an option to skip replication of NoteDb meta refs
Replicating NoteDb meta refs is not needed when the remote does not run
a Gerrit instance.
Provide a config `remote.<NAME>.replicateNoteDbMetaRefs` which implies
whether to replicate the NoteDb meta refs (`refs/changes/*/meta`,
`refs/changes/*/robot-comments`, `refs/draft-comments/*`,
`refs/starred-changes/*`) or not. Time taken to replicate to a
non-Gerrit replica can be improved with this change.
Change-Id: I653f2e0a5b66dcded40c11ca23d2d22c63ccc396
diff --git a/src/main/java/com/googlesource/gerrit/plugins/replication/Destination.java b/src/main/java/com/googlesource/gerrit/plugins/replication/Destination.java
index a7235d5..04af9db 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/replication/Destination.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/replication/Destination.java
@@ -803,6 +803,10 @@
return config.getPushBatchSize();
}
+ boolean replicateNoteDbMetaRefs() {
+ return config.replicateNoteDbMetaRefs();
+ }
+
private static boolean matches(URIish uri, String urlMatch) {
if (urlMatch == null || urlMatch.equals("") || urlMatch.equals("*")) {
return true;
diff --git a/src/main/java/com/googlesource/gerrit/plugins/replication/DestinationConfiguration.java b/src/main/java/com/googlesource/gerrit/plugins/replication/DestinationConfiguration.java
index a74d198..4d72ff0 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/replication/DestinationConfiguration.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/replication/DestinationConfiguration.java
@@ -39,6 +39,7 @@
private final ImmutableList<String> adminUrls;
private final int poolThreads;
private final boolean createMissingRepos;
+ private final boolean replicateNoteDbMetaRefs;
private final boolean replicatePermissions;
private final boolean replicateProjectDeletions;
private final boolean replicateHiddenProjects;
@@ -71,6 +72,7 @@
"updateRefErrorMaxRetries",
cfg.getInt("replication", "lockErrorMaxRetries", 0));
createMissingRepos = cfg.getBoolean("remote", name, "createMissingRepositories", true);
+ replicateNoteDbMetaRefs = cfg.getBoolean("remote", name, "replicateNoteDbMetaRefs", true);
replicatePermissions = cfg.getBoolean("remote", name, "replicatePermissions", true);
replicateProjectDeletions = cfg.getBoolean("remote", name, "replicateProjectDeletions", false);
replicateHiddenProjects = cfg.getBoolean("remote", name, "replicateHiddenProjects", false);
@@ -177,6 +179,11 @@
return createMissingRepos;
}
+ @Override
+ public boolean replicateNoteDbMetaRefs() {
+ return replicateNoteDbMetaRefs;
+ }
+
public boolean replicateProjectDeletions() {
return replicateProjectDeletions;
}
diff --git a/src/main/java/com/googlesource/gerrit/plugins/replication/PushOne.java b/src/main/java/com/googlesource/gerrit/plugins/replication/PushOne.java
index c36b42c..ed84087 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/replication/PushOne.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/replication/PushOne.java
@@ -750,7 +750,8 @@
private boolean canPushRef(String ref, boolean noPerms) {
return !(noPerms && RefNames.REFS_CONFIG.equals(ref))
- && !ref.startsWith(RefNames.REFS_CACHE_AUTOMERGE);
+ && !ref.startsWith(RefNames.REFS_CACHE_AUTOMERGE)
+ && !(!pool.replicateNoteDbMetaRefs() && RefNames.isNoteDbMetaRef(ref));
}
private Map<String, Ref> listRemote(Transport tn)
diff --git a/src/main/java/com/googlesource/gerrit/plugins/replication/RemoteConfiguration.java b/src/main/java/com/googlesource/gerrit/plugins/replication/RemoteConfiguration.java
index 5fe0323..05b4066 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/replication/RemoteConfiguration.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/replication/RemoteConfiguration.java
@@ -105,6 +105,13 @@
int getPushBatchSize();
/**
+ * Whether to replicate the NoteDb meta refs or not.
+ *
+ * @return boolean, true by default
+ */
+ boolean replicateNoteDbMetaRefs();
+
+ /**
* Whether the remote configuration is for a single project only
*
* @return true, when configuration is for a single project, false otherwise
diff --git a/src/main/resources/Documentation/config.md b/src/main/resources/Documentation/config.md
index 76de9e8..8f1ca86 100644
--- a/src/main/resources/Documentation/config.md
+++ b/src/main/resources/Documentation/config.md
@@ -587,6 +587,16 @@
Note that `pushBatchSize` is ignored when *Cluster Replication* is configured
- when `replication.distributionInterval` has value > 0.
+remote.NAME.replicateNoteDbMetaRefs
+: Whether to replicate the NoteDb meta refs (`refs/changes/*/meta`,
+ `refs/changes/*/robot-comments`, `refs/draft-comments/*`,
+ `refs/starred-changes/*`) or not. This setting is useful when the remote
+ replica does not run a Gerrit instance and one wants to turn off replicating
+ NoteDb meta refs to that remote.
+
+ By default, true.
+
+
Directory `replication`
--------------------
The optional directory `$site_path/etc/replication` contains Git-style
diff --git a/src/test/java/com/googlesource/gerrit/plugins/replication/PushOneTest.java b/src/test/java/com/googlesource/gerrit/plugins/replication/PushOneTest.java
index fd08b7b..8664adc 100644
--- a/src/test/java/com/googlesource/gerrit/plugins/replication/PushOneTest.java
+++ b/src/test/java/com/googlesource/gerrit/plugins/replication/PushOneTest.java
@@ -234,6 +234,7 @@
@Test
public void shouldPushMetaRefTogetherWithChangeRef() throws InterruptedException, IOException {
+ when(destinationMock.replicateNoteDbMetaRefs()).thenReturn(true);
PushOne pushOne = Mockito.spy(createPushOne(null));
Ref newLocalChangeRef =
@@ -261,6 +262,36 @@
}
@Test
+ public void skipPushingMetaRefWhenReplicateNoteDbMetaRefsIsSetToFalse()
+ throws InterruptedException, IOException {
+ when(destinationMock.replicateNoteDbMetaRefs()).thenReturn(false);
+ PushOne pushOne = Mockito.spy(createPushOne(null));
+
+ Ref newLocalChangeRef =
+ new ObjectIdRef.Unpeeled(
+ NEW,
+ "refs/changes/11/11111/1",
+ ObjectId.fromString("0000000000000000000000000000000000000002"));
+
+ Ref newLocalChangeMetaRef =
+ new ObjectIdRef.Unpeeled(
+ NEW,
+ "refs/changes/11/11111/meta",
+ ObjectId.fromString("0000000000000000000000000000000000000003"));
+
+ localRefs.add(newLocalChangeRef);
+ localRefs.add(newLocalChangeMetaRef);
+
+ pushOne.addRefBatch(
+ ImmutableSet.of(newLocalChangeRef.getName(), newLocalChangeMetaRef.getName()));
+ pushOne.run();
+
+ isCallFinished.await(10, TimeUnit.SECONDS);
+ verify(transportMock, atLeastOnce()).push(any(), any());
+ verify(pushOne, times(1)).push(any(), any(), any());
+ }
+
+ @Test
public void shouldNotAttemptDuplicateRemoteRefUpdate() throws InterruptedException, IOException {
PushOne pushOne = Mockito.spy(createPushOne(null));