Add --now switch to start replication right away
When starting replication from the command line, each replication task
is scheduled with the per remote replicationDelay. This delay is
considered a batching mechanism for user driven events. However,
scripts may desire to trigger replication without caring about batching.
In particular, a script may want to replicate a bunch of updates to many
projects serially for throttling reasons using the --wait option.
However, with a long list of projects to replicate the per project
replication delay can quickly add up to a lot of wasted time (too much
throttling). By adding a --now option which starts replicating without
delay, it is possible for a script to control (generally along with the
--wait option) replication throttling very accurately.
Change-Id: I35b4386f53112ffa7c886ad345e5fabb97273aa9
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 603a70f..207158c 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/replication/Destination.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/replication/Destination.java
@@ -260,6 +260,11 @@
}
void schedule(Project.NameKey project, String ref, URIish uri, ReplicationState state) {
+ schedule(project, ref, uri, state, false);
+ }
+
+ void schedule(
+ Project.NameKey project, String ref, URIish uri, ReplicationState state, boolean now) {
repLog.info("scheduling replication {}:{} => {}", project, ref, uri);
if (!shouldReplicate(project, ref, state)) {
return;
@@ -295,7 +300,7 @@
if (e == null) {
e = opFactory.create(project, uri);
addRef(e, ref);
- pool.schedule(e, config.getDelay(), TimeUnit.SECONDS);
+ pool.schedule(e, now ? 0 : config.getDelay(), TimeUnit.SECONDS);
pending.put(uri, e);
} else if (!e.getRefs().contains(ref)) {
addRef(e, ref);
diff --git a/src/main/java/com/googlesource/gerrit/plugins/replication/OnStartStop.java b/src/main/java/com/googlesource/gerrit/plugins/replication/OnStartStop.java
index a6b38c1..227804d 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/replication/OnStartStop.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/replication/OnStartStop.java
@@ -56,7 +56,9 @@
&& config.isReplicateAllOnPluginStart()) {
ReplicationState state = new ReplicationState(new GitUpdateProcessing(eventDispatcher.get()));
pushAllFuture.set(
- pushAll.create(null, ReplicationFilter.all(), state).schedule(30, TimeUnit.SECONDS));
+ pushAll
+ .create(null, ReplicationFilter.all(), state, false)
+ .schedule(30, TimeUnit.SECONDS));
}
}
diff --git a/src/main/java/com/googlesource/gerrit/plugins/replication/PushAll.java b/src/main/java/com/googlesource/gerrit/plugins/replication/PushAll.java
index da32ecd..db067e2 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/replication/PushAll.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/replication/PushAll.java
@@ -27,7 +27,7 @@
private final ReplicationStateListener stateLog;
public interface Factory {
- PushAll create(String urlMatch, ReplicationFilter filter, ReplicationState state);
+ PushAll create(String urlMatch, ReplicationFilter filter, ReplicationState state, boolean now);
}
private final WorkQueue workQueue;
@@ -36,6 +36,7 @@
private final String urlMatch;
private final ReplicationFilter filter;
private final ReplicationState state;
+ private final boolean now;
@Inject
protected PushAll(
@@ -45,7 +46,8 @@
ReplicationStateListener stateLog,
@Assisted @Nullable String urlMatch,
@Assisted ReplicationFilter filter,
- @Assisted ReplicationState state) {
+ @Assisted ReplicationState state,
+ @Assisted boolean now) {
this.workQueue = wq;
this.projectCache = projectCache;
this.replication = rq;
@@ -53,6 +55,7 @@
this.urlMatch = urlMatch;
this.filter = filter;
this.state = state;
+ this.now = now;
}
Future<?> schedule(long delay, TimeUnit unit) {
@@ -64,7 +67,7 @@
try {
for (Project.NameKey nameKey : projectCache.all()) {
if (filter.matches(nameKey)) {
- replication.scheduleFullSync(nameKey, urlMatch, state);
+ replication.scheduleFullSync(nameKey, urlMatch, state, now);
}
}
} catch (Exception e) {
diff --git a/src/main/java/com/googlesource/gerrit/plugins/replication/ReplicationQueue.java b/src/main/java/com/googlesource/gerrit/plugins/replication/ReplicationQueue.java
index 9a68d32..bff4651 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/replication/ReplicationQueue.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/replication/ReplicationQueue.java
@@ -109,8 +109,12 @@
}
}
+ void scheduleFullSync(Project.NameKey project, String urlMatch, ReplicationState state) {
+ scheduleFullSync(project, urlMatch, state, false);
+ }
+
void scheduleFullSync(
- final Project.NameKey project, final String urlMatch, ReplicationState state) {
+ Project.NameKey project, String urlMatch, ReplicationState state, boolean now) {
if (!running) {
stateLog.warn("Replication plugin did not finish startup before event", state);
return;
@@ -119,7 +123,7 @@
for (Destination cfg : config.getDestinations(FilterType.ALL)) {
if (cfg.wouldPushProject(project)) {
for (URIish uri : cfg.getURIs(project, urlMatch)) {
- cfg.schedule(project, PushOne.ALL_REFS, uri, state);
+ cfg.schedule(project, PushOne.ALL_REFS, uri, state, now);
}
}
}
diff --git a/src/main/java/com/googlesource/gerrit/plugins/replication/StartCommand.java b/src/main/java/com/googlesource/gerrit/plugins/replication/StartCommand.java
index c701c21..c3f7eee 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/replication/StartCommand.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/replication/StartCommand.java
@@ -44,6 +44,9 @@
@Option(name = "--wait", usage = "wait for replication to finish before exiting")
private boolean wait;
+ @Option(name = "--now", usage = "start replication without waiting for replicationDelay")
+ private boolean now;
+
@Argument(index = 0, multiValued = true, metaVar = "PATTERN", usage = "project name pattern")
private List<String> projectPatterns = new ArrayList<>(2);
@@ -66,7 +69,7 @@
projectFilter = new ReplicationFilter(projectPatterns);
}
- future = pushFactory.create(urlMatch, projectFilter, state).schedule(0, TimeUnit.SECONDS);
+ future = pushFactory.create(urlMatch, projectFilter, state, now).schedule(0, TimeUnit.SECONDS);
if (wait) {
if (future != null) {
diff --git a/src/main/resources/Documentation/cmd-start.md b/src/main/resources/Documentation/cmd-start.md
index 59c3d1d..6af73af 100644
--- a/src/main/resources/Documentation/cmd-start.md
+++ b/src/main/resources/Documentation/cmd-start.md
@@ -9,6 +9,7 @@
--------
```
ssh -p @SSH_PORT@ @SSH_HOST@ @PLUGIN@ start
+ [--now]
[--wait]
[--url <PATTERN>]
{--all | <PROJECT PATTERN> ...}
@@ -85,6 +86,10 @@
OPTIONS
-------
+`--now`
+: Start replicating right away without waiting the per remote
+ replication delay.
+
`--wait`
: Wait for replication to finish before exiting.