检测 CompletableFuture 链中的超时
Detect timeouts in a CompletableFuture chain
是否有任何可能的安全方法来检测 CompletableFuture 链中的超时?
O someValue = CompletableFuture.supplyAsync(() -> {
...
// API Call
...
}).thenApply(o -> {
...
}).thenApply(o -> {
// If the chain has timed out, I still have 'o' ready here
// So at least cache it here, so it's available for the next request
// Even though the current request will return with a 'null'
...
}).get(10, TimeUnit.SECONDS);
// cache 'someValue'
return someValue;
它在没有超时的情况下成功完成,我可以使用 'someValue' 并用它做任何事情
如果超时,它会抛出 TimeoutException 并且我已经丢失了值,即使它仍在后台处理
我的想法是,即使它超时并且由于线程中的 API 调用仍然在后台完成并且 returns 响应,我可以使用该值,比方说,缓存
至少在你展示的方式上不是。当抛出异常时,您将失去获得 API 调用结果的任何机会,即使它已完成。您在这样的链中缓存的唯一机会如下所示,这无助于超时 API 调用自身
.thenApplyAsync(o -> {
cache = o;
// do something
}).thenApplyAsync(o -> {
cache = o;
// do something more
}).get(10, TimeUnit.SECONDS);
然而通读 this 给了我一个想法,如果你做了类似下面的事情会怎样
SynchronousQueue<Result> q = new SynchronousQueue<>();
CompletableFuture.supplyAsync(() -> {
// API call
}.thenAccept(result -> {
cache.put(result); // cache the value
q.offer(result); // offer value to main thread, if still there
}
);
// Main thread waits 10 seconds for a value to be asynchronously offered into the queue
// In case of timeout, null is returned, but any operations done
// before q.offer(result) are still performed
return queue.poll(10, TimeUnit.SECONDS);
在 10 秒内未完成的 API 调用仍被处理到缓存中,因为它是异步接受的并且超时发生在主线程而不是 CompletableFuture
链中,即使原始请求不会得到结果(我想必须优雅地处理它)。
是否有任何可能的安全方法来检测 CompletableFuture 链中的超时?
O someValue = CompletableFuture.supplyAsync(() -> {
...
// API Call
...
}).thenApply(o -> {
...
}).thenApply(o -> {
// If the chain has timed out, I still have 'o' ready here
// So at least cache it here, so it's available for the next request
// Even though the current request will return with a 'null'
...
}).get(10, TimeUnit.SECONDS);
// cache 'someValue'
return someValue;
它在没有超时的情况下成功完成,我可以使用 'someValue' 并用它做任何事情
如果超时,它会抛出 TimeoutException 并且我已经丢失了值,即使它仍在后台处理
我的想法是,即使它超时并且由于线程中的 API 调用仍然在后台完成并且 returns 响应,我可以使用该值,比方说,缓存
至少在你展示的方式上不是。当抛出异常时,您将失去获得 API 调用结果的任何机会,即使它已完成。您在这样的链中缓存的唯一机会如下所示,这无助于超时 API 调用自身
.thenApplyAsync(o -> {
cache = o;
// do something
}).thenApplyAsync(o -> {
cache = o;
// do something more
}).get(10, TimeUnit.SECONDS);
然而通读 this 给了我一个想法,如果你做了类似下面的事情会怎样
SynchronousQueue<Result> q = new SynchronousQueue<>();
CompletableFuture.supplyAsync(() -> {
// API call
}.thenAccept(result -> {
cache.put(result); // cache the value
q.offer(result); // offer value to main thread, if still there
}
);
// Main thread waits 10 seconds for a value to be asynchronously offered into the queue
// In case of timeout, null is returned, but any operations done
// before q.offer(result) are still performed
return queue.poll(10, TimeUnit.SECONDS);
在 10 秒内未完成的 API 调用仍被处理到缓存中,因为它是异步接受的并且超时发生在主线程而不是 CompletableFuture
链中,即使原始请求不会得到结果(我想必须优雅地处理它)。