Do not reload config when queue is not ready Do not stop/start the replication queue upon a new configuration added when the queue is either not running yet or is replaying incoming events. Restarting a partially initialized queue would have unexpected consequences as the objects that are needed to schedule and serve the requests could be still null and generate random NPEs all around. The replay also is a very delicate phase because it is responsible for the replay of the past missed replication events that should be re-triggered with highest priority possible. All new events and new configuration can wait to be processed once all the past events have been replayed and have completed. Bug: Issue 11055 Change-Id: Ib154532ec32a50f4cb9ca5553c1f77fa931ae2ac
diff --git a/src/main/java/com/googlesource/gerrit/plugins/replication/AutoReloadConfigDecorator.java b/src/main/java/com/googlesource/gerrit/plugins/replication/AutoReloadConfigDecorator.java index ad6e67d..5257c36 100644 --- a/src/main/java/com/googlesource/gerrit/plugins/replication/AutoReloadConfigDecorator.java +++ b/src/main/java/com/googlesource/gerrit/plugins/replication/AutoReloadConfigDecorator.java
@@ -77,9 +77,13 @@ private void reloadIfNeeded() { if (isAutoReload()) { ReplicationQueue queue = replicationQueue.get(); + long lastModified = getLastModified(currentConfig); try { - if (lastModified > currentConfigTs && lastModified > lastFailedConfigTs) { + if (lastModified > currentConfigTs + && lastModified > lastFailedConfigTs + && queue.isRunning() + && !queue.isReplaying()) { queue.stop(); currentConfig = loadConfig(); currentConfigTs = lastModified;
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 541a595..a728bf3 100644 --- a/src/main/java/com/googlesource/gerrit/plugins/replication/ReplicationQueue.java +++ b/src/main/java/com/googlesource/gerrit/plugins/replication/ReplicationQueue.java
@@ -70,6 +70,7 @@ private final ReplicationState.Factory replicationStateFactory; private final EventsStorage eventsStorage; private volatile boolean running; + private volatile boolean replaying; @Inject ReplicationQueue( @@ -107,6 +108,14 @@ } } + public boolean isRunning() { + return running; + } + + public boolean isReplaying() { + return replaying; + } + void scheduleFullSync(Project.NameKey project, String urlMatch, ReplicationState state) { scheduleFullSync(project, urlMatch, state, false); } @@ -154,9 +163,14 @@ } private void firePendingEvents() { - for (EventsStorage.ReplicateRefUpdate e : eventsStorage.list()) { - repLog.info("Firing pending event {}", e); - onGitReferenceUpdated(e.project, e.ref); + replaying = true; + try { + for (EventsStorage.ReplicateRefUpdate e : eventsStorage.list()) { + repLog.info("Firing pending event {}", e); + onGitReferenceUpdated(e.project, e.ref); + } + } finally { + replaying = false; } }