Allow polling filesystem to be run on a specified queue

The queue could be provided in the config section as explained
in the Documentation. This allows polling task to be separated
from the default core tasks.

Change-Id: Ice9e608e5765397d12ccbdf1f378d149b14abada
diff --git a/src/main/java/com/googlesource/gerrit/plugins/events/Module.java b/src/main/java/com/googlesource/gerrit/plugins/events/Module.java
index 7774a38..504f740 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/events/Module.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/events/Module.java
@@ -41,6 +41,13 @@
     return SECONDS.toMillis(ConfigUtil.getTimeUnit(fromConfig, DEFAULT_POLLING_INTERVAL, SECONDS));
   }
 
+  @Provides
+  @Singleton
+  @PollingQueue
+  protected String getPollingQueue(PluginConfigFactory cfg, @PluginName String pluginName) {
+    return Strings.nullToEmpty(cfg.getFromGerritConfig(pluginName).getString("queue"));
+  }
+
   @Override
   protected void configure() {
     DynamicSet.setOf(binder(), StreamEventListener.class);
diff --git a/src/main/java/com/googlesource/gerrit/plugins/events/PollingQueue.java b/src/main/java/com/googlesource/gerrit/plugins/events/PollingQueue.java
new file mode 100644
index 0000000..375b11b
--- /dev/null
+++ b/src/main/java/com/googlesource/gerrit/plugins/events/PollingQueue.java
@@ -0,0 +1,24 @@
+// Copyright (C) 2022 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package com.googlesource.gerrit.plugins.events;
+
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+import com.google.inject.BindingAnnotation;
+import java.lang.annotation.Retention;
+
+@Retention(RUNTIME)
+@BindingAnnotation
+public @interface PollingQueue {}
diff --git a/src/main/java/com/googlesource/gerrit/plugins/events/fsstore/FsListener.java b/src/main/java/com/googlesource/gerrit/plugins/events/fsstore/FsListener.java
index 543b9d9..7327700 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/events/fsstore/FsListener.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/events/fsstore/FsListener.java
@@ -24,11 +24,14 @@
 import com.google.inject.Singleton;
 import com.googlesource.gerrit.plugins.events.FileSystemEventBroker;
 import com.googlesource.gerrit.plugins.events.PollingInterval;
+import com.googlesource.gerrit.plugins.events.PollingQueue;
+import java.util.concurrent.ScheduledExecutorService;
 import java.util.concurrent.ScheduledFuture;
 
 @Singleton
 public class FsListener implements Runnable {
   public static class FsLifecycleListener implements LifecycleListener {
+    protected final String workQueue;
     protected final WorkQueue queue;
     protected final long pollingInterval;
     protected final FileSystemEventBroker broker;
@@ -36,20 +39,26 @@
 
     @Inject
     protected FsLifecycleListener(
-        WorkQueue queue, @PollingInterval long pollingInterval, EventDispatcher dispatcher) {
+        WorkQueue queue,
+        @PollingInterval long pollingInterval,
+        EventDispatcher dispatcher,
+        @PollingQueue String workQueue) {
       this.queue = queue;
       this.pollingInterval = pollingInterval;
       this.broker = (FileSystemEventBroker) dispatcher;
+      this.workQueue = workQueue;
     }
 
     @Override
     public void start() {
       if (pollingInterval > 0) {
+        ScheduledExecutorService executor = queue.getExecutor(workQueue);
+        if (executor == null) {
+          executor = queue.getDefaultQueue();
+        }
         future =
-            queue
-                .getDefaultQueue()
-                .scheduleAtFixedRate(
-                    new FsListener(broker), pollingInterval, pollingInterval, MILLISECONDS);
+            executor.scheduleAtFixedRate(
+                new FsListener(broker), pollingInterval, pollingInterval, MILLISECONDS);
       }
     }
 
diff --git a/src/main/resources/Documentation/config.md b/src/main/resources/Documentation/config.md
index 2fef2db..cf01fd3 100644
--- a/src/main/resources/Documentation/config.md
+++ b/src/main/resources/Documentation/config.md
@@ -14,7 +14,12 @@
 
 Reload the plugin on each primary for the changes to take effect.
 
-The polling frequency can be specified in the configuration.
+Config
+------
+
+`pollingInterval`
+
+: The polling frequency can be specified in the configuration.
 For example:
 
 ```
@@ -38,3 +43,17 @@
 
 If 'pollingInterval' is not present in the configuration, polling
 will not be enabled.
+
+`queue`
+
+: The work queue on which the polling is scheduled can be provided
+using the queue option. Example
+
+```
+  [plugin "@PLUGIN@"]
+    queue = myQueue
+```
+
+causes polling to be scheduled on myQueue executor. If the specified
+queue is not found or the queue is not specified, default queue
+(WorkQueue) is used.