简体   繁体   English

CompletableFuture - 聚合未来快速失败

[英]CompletableFuture — Aggregate Future to Fail Fast

I have been using the CompletableFuture.allOf(...) helper to create aggregate futures that will only become "done" when their composite futures are marked as complete, ie: 我一直在使用CompletableFuture.allOf(...)帮助器来创建聚合期货,这些期货只有在其复合期货被标记为完成时才会“完成”,即:

CompletableFuture<?> future1 = new CompletableFuture<>();
CompletableFuture<?> future2 = new CompletableFuture<>();
CompletableFuture<?> future3 = new CompletableFuture<>();

CompletableFuture<?> future = CompletableFuture.allOf(future1, future2, future3);

I would like a slight variation on this functionality, where the aggregate future is market as complete when: 我希望这个功能略有不同,在以下情况下,总体未来市场是完整的:

  • All futures have completed successfully OR 所有期货都已成功完成OR
  • Any one future has completed unsuccessfuly 任何一个未来都没有成功完成

In the latter case, the aggregate future should complete (exceptionally) immediately, and not have to wait for the other futures to complete, ie to fail-fast . 在后一种情况下,总体未来应该立即完成(例外),而不必等待其他期货完成,即失败快速

To illustrate this in contrast to CompletableFuture.allOf(...) consider this: 为了说明这与CompletableFuture.allOf(...)相反,请考虑以下情况:

// First future completed, gotta wait for the rest of them...
future1.complete(null);
System.out.println("Future1 Complete, aggregate status: " + future.isDone());

// Second feature was erroneous! I'd like the aggregate to now be completed with failure
future2.completeExceptionally(new Exception());
System.out.println("Future2 Complete, aggregate status: " + future.isDone());

// Finally complete the third future, that will mark the aggregate as done
future3.complete(null);
System.out.println("Future3 Complete, aggregate status: " + future.isDone());

Using allOf(...) , this code yields: 使用allOf(...) ,此代码产生:

Future1 Complete, aggregate status: false
Future2 Complete, aggregate status: false
Future3 Complete, aggregate status: true

Whereas my alternative aggregate implementation would return "true" after Feature2 was completed, given it was an exceptional. 鉴于它是一个例外,我的替代聚合实现将在Feature2完成后返回“true”。


I cannot find any utils in the Java standard library that will help me achieve this, which feels strange... given it's a relatively vanilla use-case. 我在Java标准库中找不到任何可以帮助我实现这一点的工具,这感觉很奇怪......因为它是一个相对普通的用例。

Looking at the implementation of CompletableFuture.allOf(...) it's fairly obvious that the logic behind these scenarios is fairly complex. 看看CompletableFuture.allOf(...)的实现,很明显这些场景背后的逻辑相当复杂。 I'd loathe to have to write this myself, I was wondering if there are any alternatives? 我不愿意自己写这个,我想知道是否有其他选择?

Although not as syntactically sweet as the CompletableFuture.allOf(...) method, it appears that thenCompose(...) may offer the solution: 尽管不像CompletableFuture.allOf(...)方法那样语法上很甜,但似乎thenCompose(...)可以提供解决方案:

CompletableFuture<?> future = future1.thenCompose((f) -> future2).thenCompose((f) -> future3);

This will yield the desired: 这将产生所需的:

Future1 Complete, aggregate status: false
Future2 Complete, aggregate status: true
Future3 Complete, aggregate status: true

This could be wrapped up in a helper method which would offer some syntactic niceties to the caller: 这可以包含在一个帮助方法中,它可以为调用者提供一些语法细节:

private static CompletableFuture<?> composed(CompletableFuture<?> ... futures) {

    // Complete when ALL the underlying futures are completed
    CompletableFuture<?> allComplete = CompletableFuture.allOf(futures);

    // Complete when ANY of the underlying futures are exceptional
    CompletableFuture<?> anyException = new CompletableFuture<>();
    for (CompletableFuture<?> completableFuture : futures) {
        completableFuture.exceptionally((t) -> {
            anyException.completeExceptionally(t);
            return null;
        });
    }

    // Complete when either of the above are satisfied
    return CompletableFuture.anyOf(allComplete, anyException);
}

Allowing for: 允许:

CompletableFuture<?> future = composed(future1, future2, future3);

您可以通过创建allOf和anyOf,然后将它们组合成第二个anyOf来实现。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM