JAL-3878 Add web service executor class and instantiate for each alignment viewport.
[jalview.git] / src / jalview / ws2 / WebServiceExecutor.java
index 8959dd6..453e6ce 100644 (file)
@@ -10,76 +10,112 @@ import java.util.concurrent.ScheduledExecutorService;
 import java.util.concurrent.TimeUnit;
 
 import jalview.bin.Cache;
-import jalview.ws2.WebServiceWorkerI.WSJob;
 
 public class WebServiceExecutor
 {
   private ScheduledExecutorService executor =
       Executors.newSingleThreadScheduledExecutor();
-  
+
   public void submit(final WebServiceWorkerI worker)
   {
-    for (var job : worker.getJobs()) {
-      executor.submit(() -> submitJob(worker, job));
-      executor.schedule(() -> pollJob(worker, job), 1, TimeUnit.SECONDS);
-    }
-  }
-  
-  private void submitJob(WebServiceWorkerI worker, WSJob job) {
-    try {
-      job.setJobID(worker.startJob(job).getJobID());
-      job.resetAllowedExceptions();
-      executor.schedule(() -> pollJob(worker, job), 1, TimeUnit.SECONDS);
-    }
-    catch (IOException e) {
-      Cache.log.error("Exception occurred during job submission", e);
-      if (!job.deductAllowedExceptions()) {
-        job.setState(WSJobState.SERVER_ERROR);
+    executor.submit(() -> {
+        try {
+          worker.startJobs();
+          wsThreadSupport.submitted(worker);
+        }
+        catch (Exception e) {
+          Cache.log.error("Failed to submit web service jobs.", e);
+          wsThreadSupport.submissionFailed(worker, e);
+          return;
+        }
+        executor.schedule(() -> pollJobs(worker), 1, TimeUnit.SECONDS);
       }
-    }
-    if (!job.getState().isSubmitted()) {
-      executor.schedule(() -> submitJob(worker, job), 5, TimeUnit.SECONDS);
-    }
-  }
-  
-  private void pollJob(WebServiceWorkerI worker, WSJob job) {
+    );
+    executor.schedule(() -> pollJobs(worker), 1, TimeUnit.SECONDS);
+}
+
+
+  private void pollJobs(WebServiceWorkerI worker) {
     try {
-      worker.pollJob(job);
-      job.resetAllowedExceptions();
+      worker.pollJobs();
     }
-    catch (IOException e) {
-      Cache.log.error("Exception occurred duringn job pollign", e);
-      if (!job.deductAllowedExceptions()) {
-        job.setState(WSJobState.SERVER_ERROR);
+    catch (Exception e) {
+      Cache.log.error("Failed to poll web service jobs.", e);
+      for (WSJob job : worker.getJobs()) {
+        job.setStatus(WSJobStatus.SERVER_ERROR);
       }
+      wsThreadSupport.pollFailed(worker, e);
+      return;
     }
-    if (!job.getState().isDone()) {
-      executor.schedule(() -> pollJob(worker, job), 1, TimeUnit.SECONDS);
+    if (!worker.isDone()) {
+      executor.schedule(() -> pollJobs(worker), 1, TimeUnit.SECONDS);
     }
+    else {
+      worker.done();
+      wsThreadSupport.done(worker);
+    }
+  }
+
+  private WebServiceThreadSupport wsThreadSupport = new WebServiceThreadSupport();
+
+  public void addThreadListener(WebServiceThreadListenerI listener)
+  {
+    wsThreadSupport.addListener(listener);
   }
-  
-  public static interface WebServiceThreadListenerI
+
+  public void removeThreadListener(WebServiceThreadListenerI listener)
+  {
+    wsThreadSupport.removeListener(listener);
+  }
+
+
+  public void shutdown()
   {
-    public void threadSubmitted(WebServiceWorkerI thread);
-    public void threadStarted(WebServiceWorkerI thread);
-    public void stateChanged(WebServiceWorkerI thread, WSJobState oldState,
-        WSJobState newState);
-    public void logAppended(WebServiceWorkerI thread, String text);
-    public void errorLogAppended(WebServiceWorkerI thread, String text);
-    public void cancelled(WebServiceWorkerI thread);
+    executor.shutdownNow();
   }
-  
-  
+
+}
+
+
+class WebServiceThreadSupport implements WebServiceThreadListenerI {
   List<WebServiceThreadListenerI> listeners = new CopyOnWriteArrayList<>();
-  
-  public void addServiceListener(WebServiceThreadListenerI listener)
+
+  @Override
+  public void submitted(WebServiceWorkerI thread)
   {
-    if (!listeners.contains(listener))
-      listeners.add(listener);
+    for (var listener : listeners) listener.submitted(thread);
   }
-  
-  public void removeServiceListener(WebServiceThreadListenerI listener)
+
+  @Override
+  public void submissionFailed(WebServiceWorkerI thread, Exception e)
   {
+    for (var listener : listeners) listener.submissionFailed(thread, e);
+  }
+
+  @Override
+  public void pollFailed(WebServiceWorkerI thread, Exception e) {
+    for (var listener : listeners) listener.pollFailed(thread, e);
+  }
+
+  @Override
+  public void cancelled(WebServiceWorkerI thread)
+  {
+    for (var listener : listeners) listener.cancelled(thread);
+  }
+
+  @Override
+  public void done(WebServiceWorkerI thread)
+  {
+    for (var listener : listeners) listener.done(thread);
+  }
+
+  public void addListener(WebServiceThreadListenerI listener) {
+    if (!listeners.contains(listener)) {
+      listeners.add(listener);
+    }
+  }
+
+  public void removeListener(WebServiceThreadListenerI listener) {
     listeners.remove(listener);
   }
 }