1 package jalview.ws2.actions;
3 import java.io.IOException;
4 import java.util.Collections;
6 import java.util.Objects;
7 import java.util.WeakHashMap;
8 import java.util.concurrent.CancellationException;
9 import java.util.concurrent.CompletionException;
10 import java.util.concurrent.Future;
11 import java.util.concurrent.ScheduledExecutorService;
12 import java.util.concurrent.TimeUnit;
14 import jalview.ws2.actions.api.TaskI;
16 public class PollingTaskExecutor
18 private static final Map<ScheduledExecutorService, PollingTaskExecutor> executorPool =
19 Collections.synchronizedMap(new WeakHashMap<>());
21 public static PollingTaskExecutor fromPool(ScheduledExecutorService executor)
23 return executorPool.computeIfAbsent(executor, PollingTaskExecutor::new);
26 private final ScheduledExecutorService executor;
28 public PollingTaskExecutor(ScheduledExecutorService executor)
30 this.executor = executor;
33 public Future<?> submit(TaskI<?> task)
35 Objects.requireNonNull(task);
36 return executor.scheduleWithFixedDelay(
37 new TaskRunnable(task), 2, 2, TimeUnit.SECONDS);
40 private static class TaskRunnable implements Runnable
42 private final TaskI<?> task;
44 private static final int STAGE_INIT = 0;
46 private static final int STAGE_POLLING = 2;
48 private static final int STAGE_FINISHED = 3;
50 private static final int STAGE_STOPPED = 4;
52 private int stage = STAGE_INIT;
54 private static final int MAX_POLL_RETRY = 5;
56 private int pollRetryCount = 0;
58 private TaskRunnable(TaskI<?> task)
66 if (task.getStatus().isDone())
68 stage = STAGE_STOPPED;
70 if (stage == STAGE_INIT)
75 stage = STAGE_POLLING;
78 stage = STAGE_STOPPED;
79 throw new CompletionException(e);
84 if (stage == STAGE_POLLING && task.poll())
86 stage = STAGE_FINISHED;
88 if (stage == STAGE_FINISHED)
91 stage = STAGE_STOPPED;
95 if (++pollRetryCount > MAX_POLL_RETRY || e instanceof RuntimeException)
98 stage = STAGE_STOPPED;
99 throw new CompletionException(e);
102 if (stage == STAGE_STOPPED)
104 throw new CancellationException();