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