JAL-3878 Rename web service worker to more generic pollable task.
[jalview.git] / src / jalview / ws2 / PollingTaskExecutor.java
diff --git a/src/jalview/ws2/PollingTaskExecutor.java b/src/jalview/ws2/PollingTaskExecutor.java
new file mode 100644 (file)
index 0000000..3e04c17
--- /dev/null
@@ -0,0 +1,126 @@
+package jalview.ws2;
+
+import java.util.List;
+import java.util.concurrent.CopyOnWriteArrayList;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.TimeUnit;
+
+import jalview.bin.Cache;
+
+public class PollingTaskExecutor
+{
+  private ScheduledExecutorService executor = Executors
+          .newSingleThreadScheduledExecutor();
+
+  public void submit(final PollableTaskI task)
+  {
+    executor.submit(() -> {
+      try
+      {
+        task.start();
+        wsThreadSupport.submitted(task);
+      } catch (Exception e)
+      {
+        Cache.log.error("Failed to submit web service jobs.", e);
+        wsThreadSupport.submissionFailed(task, e);
+        return;
+      }
+      executor.schedule(() -> poll(task), 1, TimeUnit.SECONDS);
+    });
+  }
+
+  private void poll(PollableTaskI task)
+  {
+    boolean done;
+    try
+    {
+      done = task.poll();
+    } catch (Exception e)
+    {
+      Cache.log.error("Failed to poll task.", e);
+      wsThreadSupport.pollFailed(task, e);
+      return;
+    }
+    if (!done)
+    {
+      executor.schedule(() -> poll(task), 1, TimeUnit.SECONDS);
+    }
+    else
+    {
+      task.done();
+      wsThreadSupport.done(task);
+    }
+  }
+
+  private WebServiceThreadSupport wsThreadSupport = new WebServiceThreadSupport();
+
+  public void addThreadListener(PollableTaskListenerI listener)
+  {
+    wsThreadSupport.addListener(listener);
+  }
+
+  public void removeThreadListener(PollableTaskListenerI listener)
+  {
+    wsThreadSupport.removeListener(listener);
+  }
+
+  public void shutdown()
+  {
+    executor.shutdownNow();
+  }
+
+}
+
+class WebServiceThreadSupport implements PollableTaskListenerI
+{
+  List<PollableTaskListenerI> listeners = new CopyOnWriteArrayList<>();
+
+  @Override
+  public void submitted(PollableTaskI task)
+  {
+    for (var listener : listeners)
+      listener.submitted(task);
+  }
+
+  @Override
+  public void submissionFailed(PollableTaskI task, Exception e)
+  {
+    for (var listener : listeners)
+      listener.submissionFailed(task, e);
+  }
+
+  @Override
+  public void pollFailed(PollableTaskI task, Exception e)
+  {
+    for (var listener : listeners)
+      listener.pollFailed(task, e);
+  }
+
+  @Override
+  public void cancelled(PollableTaskI task)
+  {
+    for (var listener : listeners)
+      listener.cancelled(task);
+  }
+
+  @Override
+  public void done(PollableTaskI task)
+  {
+    for (var listener : listeners)
+      listener.done(task);
+  }
+
+  public void addListener(PollableTaskListenerI listener)
+  {
+    if (!listeners.contains(listener))
+    {
+      listeners.add(listener);
+    }
+  }
+
+  public void removeListener(PollableTaskListenerI listener)
+  {
+    listeners.remove(listener);
+  }
+}