I have a scenario where I have to poll a remote server checking if a task has completed. Once it has, I make a different call to retrieve the result.
I originally figured I should use a SingleThreadScheduledExecutor
with scheduleWithFixedDelay
for polling:
ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor();
ScheduledFuture future = executor.scheduleWithFixedDelay(() -> poll(jobId), 0, 10, TimeUnit.SECONDS);
public void poll(String jobId) {
boolean jobDone = remoteServer.isJobDone(jobId);
if (jobDone) {
retrieveJobResult(jobId);
}
}
But since I can only provide a Runnable
to scheduleWithFixedDelay
which can't return anything, I don't understand when the future
will be complete, if ever. What does calling future.get()
even mean? What result am I waiting for?
The first time I detect the remote task has completed, I want to execute a different remote call and set its result as the value of the future
. I figured I could use CompletableFuture for this, that I would forward to my poll
method, which would in turn forward it to my retrieveTask
method that would eventually complete it:
CompletableFuture<Object> result = new CompletableFuture<Object>();
ScheduledFuture future = executor.scheduleWithFixedDelay(() -> poll(jobId, result), 0, 10, TimeUnit.SECONDS);
public void poll(String jobId, CompletableFuture<Object> result) {
boolean jobDone = remoteServer.isJobDone(jobId);
if (jobDone) {
retrieveJobResult(jobId, result);
}
}
public void retrieveJobResult(String jobId, CompletableFuture<Object> result) {
Object remoteResult = remoteServer.getJobResult(jobId);
result.complete(remoteResult);
}
But this has a ton of issues. For one, CompletableFuture
doesn't even seem to be intended for this kind of use. Instead I should be doing CompletableFuture.supplyAsync(() -> poll(jobId))
I think, but how would I then properly shutdown the executor
and cancel the future
it returned when my CompletableFuture
is canceled/complete? It feels like polling should be implemented in some completely different way.