Clarify logging when replication start hits a persist-only remote A remote configured with threads=0 persists ref updates to ReplicationTasksStorage for another node to pick up, but never increments the push task count. Running `replication start --wait` against such a remote therefore printed "No replication scheduled.", which reads as if nothing happened even though the refs were persisted. Change-Id: I769e97c4b1f1b87267e3fc24ac054218a460dbbe
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 f17b50b..5704255 100644 --- a/src/main/java/com/googlesource/gerrit/plugins/replication/Destination.java +++ b/src/main/java/com/googlesource/gerrit/plugins/replication/Destination.java
@@ -467,6 +467,11 @@ boolean now, boolean fromStorage) { if (!isPushEnabled()) { + state.addPersistOnlyRemote(getRemoteConfigName()); + repLog.atFine().log( + "Not scheduling push for %s:%s => %s; remote %s is persist-only (threads=0)," + + " task was written to task storage for another node to push", + project, refs, uri, getRemoteConfigName()); return; } ImmutableSet.Builder<String> toSchedule = ImmutableSet.builder();
diff --git a/src/main/java/com/googlesource/gerrit/plugins/replication/ReplicationStarter.java b/src/main/java/com/googlesource/gerrit/plugins/replication/ReplicationStarter.java index fc88c34..39669e3 100644 --- a/src/main/java/com/googlesource/gerrit/plugins/replication/ReplicationStarter.java +++ b/src/main/java/com/googlesource/gerrit/plugins/replication/ReplicationStarter.java
@@ -23,6 +23,7 @@ import java.util.concurrent.ExecutionException; import java.util.concurrent.Future; import java.util.concurrent.TimeUnit; +import java.util.stream.Collectors; @Singleton class ReplicationStarter { @@ -70,6 +71,17 @@ } catch (InterruptedException e) { processing.writeStdErr("We are interrupted while waiting replication to complete"); } + if (state.hasPersistOnlyRemotes()) { + processing.writeStdOut( + "Note: replication task(s) for persist-only remote(s) " + + formatRemotes(state) + + " were also written to task storage for another node to push"); + } + } else if (state.hasPersistOnlyRemotes()) { + processing.writeStdOut( + "No pushes performed by this node. Replication task(s) for persist-only remote(s) " + + formatRemotes(state) + + " were written to task storage for another node to push"); } else { processing.writeStdOut( "WARNING: No replication scheduled. No configured destination matched the requested" @@ -79,6 +91,10 @@ } } + private static String formatRemotes(ReplicationState state) { + return state.getPersistOnlyRemotes().stream().sorted().collect(Collectors.joining(", ")); + } + void start( @Nullable String urlMatch, String refName,
diff --git a/src/main/java/com/googlesource/gerrit/plugins/replication/ReplicationState.java b/src/main/java/com/googlesource/gerrit/plugins/replication/ReplicationState.java index fa65803..b375737 100644 --- a/src/main/java/com/googlesource/gerrit/plugins/replication/ReplicationState.java +++ b/src/main/java/com/googlesource/gerrit/plugins/replication/ReplicationState.java
@@ -16,6 +16,8 @@ import com.google.common.collect.HashBasedTable; import com.google.common.collect.Table; +import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.CountDownLatch; import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.locks.Lock; @@ -50,6 +52,7 @@ private final Table<String, String, RefReplicationStatus> statusByProjectRef; private final AtomicInteger totalPushTasksCount = new AtomicInteger(); private final AtomicInteger finishedPushTasksCount = new AtomicInteger(); + private final Set<String> persistOnlyRemotes = ConcurrentHashMap.newKeySet(); ReplicationState(PushResultProcessing processing) { pushResultProcessing = processing; @@ -70,6 +73,19 @@ return totalPushTasksCount.get() != 0; } + /** Records that a task was persisted for a remote that does not push (e.g. persist-only). */ + public void addPersistOnlyRemote(String remoteName) { + persistOnlyRemotes.add(remoteName); + } + + public boolean hasPersistOnlyRemotes() { + return !persistOnlyRemotes.isEmpty(); + } + + public Set<String> getPersistOnlyRemotes() { + return persistOnlyRemotes; + } + public void notifyRefReplicated( String project, String ref,
diff --git a/src/main/resources/Documentation/cmd-start.md b/src/main/resources/Documentation/cmd-start.md index 724728e..8676693 100644 --- a/src/main/resources/Documentation/cmd-start.md +++ b/src/main/resources/Documentation/cmd-start.md
@@ -63,6 +63,10 @@ pattern in command options, or the authGroup in the `replication.config` has no read access for the replicated projects. +If the message instead says replication tasks were written to the task +storage for another node to push, this is expected for a remote +configured with `threads = 0` and does not indicate a problem. + If one or several project patterns are supplied, only those projects conforming to both this/these pattern(s) and those defined in `replication.config` for the target host(s) are queued for replication.