如何记录CompletableFuture的completeOnTimeout超时完成情况?
解决CompletableFuture超时日志记录问题
直接在completeOnTimeout中用lambda实现超时日志记录是不可行的——因为completeOnTimeout的第一个参数是预定义的结果值,不是延迟执行的回调逻辑,它会在调用该方法时就创建好结果,而非超时触发时才执行日志逻辑。
不过可以通过两种可靠方式实现超时日志记录:
方式一:结合orTimeout与exceptionally(推荐)
用orTimeout替代completeOnTimeout,它会在超时抛出TimeoutException,再通过exceptionally捕获异常并记录日志,同时返回空对象,效果和completeOnTimeout一致:
return CompletableFuture.supplyAsync(() -> { try { log.info("#####Start sleeping"); Thread.sleep(9000); log.info("#####Finished sleeping"); } catch (InterruptedException e){ log.info("#####Interrupted"); } TestEntity reputationEntity = getTestEntity(destination); return getTestDTO(destination, accountId, reputationEntity); }) .orTimeout(asyncTimeoutMls, TimeUnit.MILLISECONDS) .exceptionally(ex -> { if (ex.getCause() instanceof TimeoutException) { log.info("##### Future针对destination: {} 超时完成", destination); } else { log.error("##### Future执行异常", ex); } return new TestDTO(); });
方式二:给超时结果添加标记(配合后续检查)
如果一定要保留completeOnTimeout,可以给超时生成的TestDTO添加一个超时标记字段,后续组合完成后逐个检查:
1. 给TestDTO增加标记
public class TestDTO { private boolean isTimeout = false; // 其他字段、getter/setter public boolean isTimeout() { return isTimeout; } public void setTimeout(boolean timeout) { isTimeout = timeout; } }
2. 超时返回带标记的对象
return CompletableFuture.supplyAsync(() -> { // 原有异步逻辑 try { log.info("#####Start sleeping"); Thread.sleep(9000); log.info("#####Finished sleeping"); } catch (InterruptedException e){ log.info("#####Interrupted"); } TestEntity reputationEntity = getTestEntity(destination); return getTestDTO(destination, accountId, reputationEntity); }) .completeOnTimeout(() -> { TestDTO timeoutDTO = new TestDTO(); timeoutDTO.setTimeout(true); return timeoutDTO; }, asyncTimeoutMls, TimeUnit.MILLISECONDS);
3. 组合完成后检查并记录
CompletableFuture.allOf(test1ComletableFuture, test2ComletableFuture).join(); if (test1ComletableFuture.get().isTimeout()) { log.info("##### test1 Future超时完成"); } if (test2ComletableFuture.get().isTimeout()) { log.info("##### test2 Future超时完成"); }
内容的提问来源于stack exchange,提问作者neverEugene
相关产品推荐
相关产品推荐

