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