如何使用ExecutorService进行轮询直到结果到达 [英] How to use ExecutorService to poll until a result arrives
问题描述
我有一个场景,我必须轮询远程服务器,检查任务是否已完成。一旦它有,我会进行不同的调用以检索结果。
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.
我原本认为我应该使用 SingleThreadScheduledExecutor
使用 scheduleWithFixedDelay
进行轮询:
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);
}
}
但由于我只能提供 Runnable
到 scheduleWithFixedDelay
哪些不能返回任何内容,我不明白何时 future $ c如果有的话,$ c>将完整。调用
future.get()
甚至意味着什么?我等待的结果是什么?
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?
我第一次检测到远程任务已完成时,我想执行一个不同的远程调用并将其结果设置为将来
。我想我可以使用CompletableFuture,我会转发到我的 poll
方法,然后将它转发到我的 retrieveTask
最终完成它的方法:
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);
}
但这有很多问题。例如, CompletableFuture
似乎甚至不打算用于此类用途。相反,我应该做 CompletableFuture.supplyAsync(() - > poll(jobId))
我想,但我怎么能正确关闭执行者
并取消 CompletableFuture
取消/完成时返回的 future
?感觉轮询应该以完全不同的方式实现。
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.
推荐答案
我认为CompletableFutures是一个很好的方法:
I think CompletableFutures are a fine way to do this:
ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor();
private void run() {
final Object jobResult = pollForCompletion("jobId1")
.thenRun(jobId -> remoteServer.getJobResult(jobId))
.get();
}
private CompletableFuture<String> pollForCompletion(String jobId) {
CompletableFuture<String> completionFuture = new CompletableFuture<>();
final ScheduledFuture<Void> checkFuture = executor.scheduleAtFixedRate(() -> {
if (remoteServer.isJobDone(jobId)) {
completionFuture.complete(jobId);
}
}, 0, 10, TimeUnit.SECONDS);
completionFuture.whenComplete((result, thrown) -> {
checkFuture.cancel(true);
});
return completionFuture;
}
这篇关于如何使用ExecutorService进行轮询直到结果到达的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!