From 8eb10400f3df3a3efc86e415e0665fa8344941e3 Mon Sep 17 00:00:00 2001 From: Jerry Lee Date: Sun, 9 Jun 2024 20:28:23 +0800 Subject: [PATCH] =?UTF-8?q?docs:=20add=20docs=20in=20`README`=20and=20java?= =?UTF-8?q?doc=20=F0=9F=93=9A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - `mostOf*` method - `default executor` --- README.md | 24 ++-- .../java/io/foldright/cffu/CffuFactory.java | 44 +++++--- .../cffu/CompletableFutureUtils.java | 104 +++++++++++------- 3 files changed, 112 insertions(+), 60 deletions(-) diff --git a/README.md b/README.md index 9a40034d..c693d361 100644 --- a/README.md +++ b/README.md @@ -69,8 +69,9 @@ - 更高效灵活的并发执行策略,如 - `allOfFastFail`方法:有`CF`失败时快速返回,而不再等待所有`CF`运行完成(`allOf`) - `anyOfSuccess`方法:返回首个成功的`CF`结果,而不是首个完成(但可能失败)的`CF`(`anyOf`) + - `mostResultsOfSuccess`方法:返回指定时间内成功`CF`的结果,忽略失败或还没有运行完成的`CF`(使用缺省值) - 更安全的使用方式,如 - - 支持设置缺省的业务线程池,`CffuFactory#builder(executor)`方法 + - 支持设置缺省的业务线程池并封装可携带,`CffuFactory#builder(executor)`方法 - 支持超时的`join`的方法,`join(timeout, unit)`方法 - 支持禁止强制篡改,`CffuFactoryBuilder#forbidObtrudeMethods`方法 - 在类方法附加完善的代码质量注解(如`@NonNull`、`@Nullable`、`@CheckReturnValue`、`@Contract`等),在编码时`IDE`能尽早提示出问题 @@ -97,8 +98,8 @@ - 无需额外依赖,几乎总是可用 - 相信有极高的实现质量 - **广为人知广泛使用,有一流的群众基础** - - `CompletableFuture`在2014年发布的`Java 8`提供,有~10年了 - - `CompletableFuture`的父接口[`Future`](https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/util/concurrent/Future.html)早在2004年发布的`Java 5`中提供,有~20年了 + - `CompletableFuture`在2014年发布的`Java 8`提供,有10年了 + - `CompletableFuture`的父接口[`Future`](https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/util/concurrent/Future.html)早在2004年发布的`Java 5`中提供,有20年了 - 虽然`Future`接口不支持 执行结果的异步获取与并发执行逻辑的编排,但也让广大`Java`开发者熟悉了`Future`这个典型的概念与工具 - **功能强大、但不会非常庞大复杂** - 足以应对日常的业务需求开发 @@ -132,7 +133,7 @@ - 🛠️️ 2) **使用`CompletableFutureUtils`工具类** - 如果你不想在项目中引入新类(`Cffu`类)、觉得这样增加了复杂性的话, - 完全可以把`cffu`库作为一个工具类来用 - - 优化`CompletableFuture`使用的工具方法在业务项目中很常见,`CompletableFutureUtils`提供了一系列实用可靠的工具方法 + - 优化`CompletableFuture`使用的工具方法在业务项目中很常见,`CompletableFutureUtils`提供了一系列实用可靠高效安全的工具方法 - 这种使用方式有些`cffu`功能没有提供(也没有想到实现方案) 😔 如支持设置缺省的业务线程池、禁止强制篡改 - 依赖`io.foldright:cffu`库 @@ -273,7 +274,7 @@ fun main() { ### 2.1 返回多个运行`CF`的结果 `CompletableFuture`的`allOf`方法没有返回结果,只是返回`Void`,不方便获得所运行的多个`CF`结果。 -\# 要再通过入参`CF`的`get`方法来获取结果。 +\# 需要在`allOf`方法之后再通过入参`CF`的读方法(如`join`/`get)`来获取结果。 `cffu`的`allResultsOf`方法提供了返回多个`CF`结果的功能。 @@ -350,13 +351,17 @@ public class AllTupleOfDemo { > \# 完整可运行的Demo代码参见[`AllTupleOfDemo.java`](cffu-core/src/test/java/io/foldright/demo/AllTupleOfDemo.java)。 -### 2.2 支持设置缺省的业务线程池 +### 2.2 支持设置缺省的业务线程池并封装可携带 - `CompletableFuture`执行执行(即`CompletableFuture`的`*Async`方法),使用的缺省线程池是`ForkJoinPool.commonPool()`。 - 这个线程池差不多是`CPU`个线程,合适执行`CPU`密集的任务;对于业务逻辑,往往有很多等待操作(如网络`IO`、阻塞等待),并不是`CPU`密集的。 - 业务使用这个缺省线程池`ForkJoinPool.commonPool()`是很危险的❗ -结果就是,业务调用`CompletableFuture`的`*Async`方法时,几乎每次都要反复传入业务线程池;这让`CompletableFuture`的使用很繁琐易错 🤯 +结果就是, + +- 在业务逻辑中,调用`CompletableFuture`的`*Async`方法时,几乎每次都要反复传入指定的业务线程池;这让`CompletableFuture`的使用很繁琐易错 🤯 +- 在底层逻辑中,当底层操作回调业务时(如`RPC`回调),不合适或方便为业务提供线程池;这时使用`Cffu`封装携带的线程池既方便又合理安全 + 这个使用场景更多可以看看[CompletableFuture原理与实践 - 4.2.3 异步RPC调用注意不要阻塞IO线程池](https://juejin.cn/post/7098727514725416967#heading-25) 示例代码如下: @@ -409,7 +414,7 @@ public class DefaultExecutorSettingForCffu { > \# 完整可运行的Demo代码参见[`DefaultExecutorSettingForCffu.java`](cffu-core/src/test/java/io/foldright/demo/DefaultExecutorSettingForCffu.java)。 -### 2.3 高效灵活的并发执行策略(`allOfFastFail`/`anyOfSuccess`) +### 2.3 高效灵活的并发执行策略(`allOfFastFail`/`anyOfSuccess`/`mostResultsOfSuccess`) - `CompletableFuture`的`allOf`方法会等待所有输入`CF`运行完成;即使有`CF`失败了也要等待后续`CF`运行完成,再返回一个失败的`CF`。 - 对于业务逻辑来说,这样失败且继续等待策略,减慢了业务响应性;会希望如果有输入`CF`失败了,则快速失败不再做于事无补的等待 @@ -419,6 +424,9 @@ public class DefaultExecutorSettingForCffu { - 对于业务逻辑来说,会希望赛马模式返回首个成功的`CF`结果,而不是首个完成但失败的`CF` - `cffu`提供了相应的`anyOfSuccess`方法 - `anyOfSuccess`只有当所有的输入`CF`都失败时,才返回失败结果 +- 返回指定时间内成功`CF`的结果,忽略失败或还没有运行完成的`CF`(使用缺省值) + - 业务最终一致性时,能返回就尽量返回有的;对于没有及时返回还在运行中处理的`CF`,结果会写到分布式缓存中避免重复计算,下次就有了 + - 这是个常见业务使用模式,`cffu`提供了相应的`mostResultsOfSuccess`方法 > 📔 关于多个`CF`的并发执行策略,可以看看`JavaScript`规范[`Promise Concurrency`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise#promise_concurrency);在`JavaScript`中,`Promise`即对应`CompletableFuture`。 > diff --git a/cffu-core/src/main/java/io/foldright/cffu/CffuFactory.java b/cffu-core/src/main/java/io/foldright/cffu/CffuFactory.java index 402940ff..f08466f9 100644 --- a/cffu-core/src/main/java/io/foldright/cffu/CffuFactory.java +++ b/cffu-core/src/main/java/io/foldright/cffu/CffuFactory.java @@ -228,10 +228,10 @@ public Cffu supplyAsync(Supplier supplier, Executor executor) { *

* In general, should not use this method in biz code, prefer below factory methods of Cffu: * - *

    + *
      *
    • {@link #runAsync(Runnable)} *
    • {@link #supplyAsync(Supplier, Executor)} - *
+ * * * @see #runAsync(Runnable) * @see #runAsync(Runnable, Executor) @@ -298,25 +298,33 @@ public final Cffu[] toCffuArray(CompletionStage... stages) { * Cffu({@code Cffu}), but may be obtained by inspecting them individually. * If no stages are provided, returns a Cffu completed with the value {@code null}. *

- * if you need the results of given stages, prefer below methods: - *

    + * This method is the same as {@link CompletableFuture#allOf(CompletableFuture[])}, + * except that the parameter type is more generic {@link CompletionStage} instead of {@link CompletableFuture}. + *

    + * If you need the results of given stages, prefer below methods: + *

      *
    • {@link #allResultsOf(CompletionStage[])} *
    • {@link #allTupleOf(CompletionStage, CompletionStage)} / * {@link #allTupleOf(CompletionStage, CompletionStage, CompletionStage, CompletionStage, CompletionStage)} * (provided overloaded methods with 2~5 input) - *
+ * *

- * This method is the same as {@link CompletableFuture#allOf(CompletableFuture[])}, - * except that the parameter type is more generic {@link CompletionStage} instead of {@link CompletableFuture}. + * If you need the successful results of given stages in the given time, prefer below methods: + *

    + *
  • {@link #mostResultsOfSuccess(long, TimeUnit, Object, CompletionStage[])} + *
  • {@link #mostTupleOfSuccess(long, TimeUnit, CompletionStage, CompletionStage)} + *
  • {@link #mostTupleOfSuccess(long, TimeUnit, CompletionStage, CompletionStage, CompletionStage, CompletionStage, CompletionStage)} + *
* * @param cfs the stages * @return a new Cffu that is completed when all the given stages complete * @throws NullPointerException if the array or any of its elements are {@code null} * @see #allResultsOf(CompletionStage[]) * @see #allTupleOf(CompletionStage, CompletionStage) - * @see #allTupleOf(CompletionStage, CompletionStage, CompletionStage) - * @see #allTupleOf(CompletionStage, CompletionStage, CompletionStage, CompletionStage) * @see #allTupleOf(CompletionStage, CompletionStage, CompletionStage, CompletionStage, CompletionStage) + * @see #mostResultsOfSuccess(long, TimeUnit, Object, CompletionStage[]) + * @see #mostTupleOfSuccess(long, TimeUnit, CompletionStage, CompletionStage) + * @see #mostTupleOfSuccess(long, TimeUnit, CompletionStage, CompletionStage, CompletionStage, CompletionStage, CompletionStage) * @see CompletableFutureUtils#allOf(CompletionStage[]) */ @Contract(pure = true) @@ -354,24 +362,32 @@ public final Cffu> allResultsOf(CompletionStage... cfs) * but may be obtained by inspecting them individually. * If no stages are provided, returns a Cffu completed with the value {@code null}. *

+ * This method is the same as {@link #allOf(CompletionStage[])} except for the fast-fail behavior. + *

* If you need the results of given stages, prefer below methods: - *

    + *
      *
    • {@link #allResultsOfFastFail(CompletionStage[])} *
    • {@link #allTupleOfFastFail(CompletionStage, CompletionStage)} / * {@link #allTupleOfFastFail(CompletionStage, CompletionStage, CompletionStage, CompletionStage, CompletionStage)} * (provided overloaded methods with 2~5 input) - *
+ * *

- * This method is the same as {@link #allOf(CompletionStage[])} except for the fast-fail behavior. + * If you need the successful results of given stages in the given time, prefer below methods: + *

    + *
  • {@link #mostResultsOfSuccess(long, TimeUnit, Object, CompletionStage[])} + *
  • {@link #mostTupleOfSuccess(long, TimeUnit, CompletionStage, CompletionStage)} + *
  • {@link #mostTupleOfSuccess(long, TimeUnit, CompletionStage, CompletionStage, CompletionStage, CompletionStage, CompletionStage)} + *
* * @param cfs the stages * @return a new Cffu that is successful when all the given stages success * @throws NullPointerException if the array or any of its elements are {@code null} * @see #allResultsOfFastFail(CompletionStage[]) * @see #allTupleOfFastFail(CompletionStage, CompletionStage) - * @see #allTupleOfFastFail(CompletionStage, CompletionStage, CompletionStage) - * @see #allTupleOfFastFail(CompletionStage, CompletionStage, CompletionStage, CompletionStage) * @see #allTupleOfFastFail(CompletionStage, CompletionStage, CompletionStage, CompletionStage, CompletionStage) + * @see #mostResultsOfSuccess(long, TimeUnit, Object, CompletionStage[]) + * @see #mostTupleOfSuccess(long, TimeUnit, CompletionStage, CompletionStage) + * @see #mostTupleOfSuccess(long, TimeUnit, CompletionStage, CompletionStage, CompletionStage, CompletionStage, CompletionStage) * @see #allOf(CompletionStage[]) */ @Contract(pure = true) diff --git a/cffu-core/src/main/java/io/foldright/cffu/CompletableFutureUtils.java b/cffu-core/src/main/java/io/foldright/cffu/CompletableFutureUtils.java index 70223e9b..5bee67ec 100644 --- a/cffu-core/src/main/java/io/foldright/cffu/CompletableFutureUtils.java +++ b/cffu-core/src/main/java/io/foldright/cffu/CompletableFutureUtils.java @@ -43,7 +43,10 @@ public final class CompletableFutureUtils { * CompletableFuture({@code CompletableFuture}), but may be obtained by inspecting them individually. * If no stages are provided, returns a CompletableFuture completed with the value {@code null}. *

- * if you need the results of given stages, prefer below methods: + * This method is the same as {@link CompletableFuture#allOf(CompletableFuture[])}, + * except that the parameter type is more generic {@link CompletionStage} instead of {@link CompletableFuture}. + *

+ * If you need the results of given stages, prefer below methods: *

    *
  • {@link #allResultsOf(CompletionStage[])} *
  • {@link #allTupleOf(CompletionStage, CompletionStage)} / @@ -51,17 +54,28 @@ public final class CompletableFutureUtils { * (provided overloaded methods with 2~5 input) *
*

- * This method is the same as {@link CompletableFuture#allOf(CompletableFuture[])}, - * except that the parameter type is more generic {@link CompletionStage} instead of {@link CompletableFuture}. + * If you need the successful results of given stages in the given time, prefer below methods: + *

    + *
  • {@link #mostResultsOfSuccess(long, TimeUnit, Object, CompletionStage[])} + *
  • {@link #mostResultsOfSuccess(Executor, long, TimeUnit, Object, CompletionStage[])} + *
  • {@link #mostTupleOfSuccess(long, TimeUnit, CompletionStage, CompletionStage)} + *
  • {@link #mostTupleOfSuccess(Executor, long, TimeUnit, CompletionStage, CompletionStage)} + *
  • {@link #mostTupleOfSuccess(long, TimeUnit, CompletionStage, CompletionStage, CompletionStage, CompletionStage, CompletionStage)} + *
  • {@link #mostTupleOfSuccess(Executor, long, TimeUnit, CompletionStage, CompletionStage, CompletionStage, CompletionStage, CompletionStage)} + *
* * @param cfs the stages * @return a new CompletableFuture that is completed when all the given stages complete * @throws NullPointerException if the array or any of its elements are {@code null} * @see #allResultsOf(CompletionStage[]) * @see #allTupleOf(CompletionStage, CompletionStage) - * @see #allTupleOf(CompletionStage, CompletionStage, CompletionStage) - * @see #allTupleOf(CompletionStage, CompletionStage, CompletionStage, CompletionStage) * @see #allTupleOf(CompletionStage, CompletionStage, CompletionStage, CompletionStage, CompletionStage) + * @see #mostResultsOfSuccess(long, TimeUnit, Object, CompletionStage[]) + * @see #mostResultsOfSuccess(Executor, long, TimeUnit, Object, CompletionStage[]) + * @see #mostTupleOfSuccess(long, TimeUnit, CompletionStage, CompletionStage) + * @see #mostTupleOfSuccess(Executor, long, TimeUnit, CompletionStage, CompletionStage) + * @see #mostTupleOfSuccess(long, TimeUnit, CompletionStage, CompletionStage, CompletionStage, CompletionStage, CompletionStage) + * @see #mostTupleOfSuccess(Executor, long, TimeUnit, CompletionStage, CompletionStage, CompletionStage, CompletionStage, CompletionStage) * @see CompletableFuture#allOf(CompletableFuture[]) */ public static CompletableFuture allOf(CompletionStage... cfs) { @@ -93,13 +107,13 @@ public static CompletableFuture allOf(CompletionStage... cfs) { @SafeVarargs public static CompletableFuture> allResultsOf(CompletionStage... cfs) { requireCfsAndEleNonNull(cfs); - final int size = cfs.length; - if (size == 0) return completedFuture(arrayList()); + final int len = cfs.length; + if (len == 0) return completedFuture(arrayList()); // Defensive copy input cf to non-minimal-stage instance(toNonMinCfCopy) for SINGLE input // in order to ensure that the returned cf is not minimal-stage CF instance(UnsupportedOperationException) - if (size == 1) return toNonMinCfCopy(cfs[0]).thenApply(CompletableFutureUtils::arrayList); + if (len == 1) return toNonMinCfCopy(cfs[0]).thenApply(CompletableFutureUtils::arrayList); - final Object[] result = new Object[size]; + final Object[] result = new Object[len]; final CompletableFuture[] resultSetterCfs = createResultSetterCfs(cfs, result); CompletableFuture> ret = CompletableFuture.allOf(resultSetterCfs) @@ -116,43 +130,57 @@ public static CompletableFuture> allResultsOf(CompletionStage + * This method is the same as {@link #allOf(CompletionStage[])} except for the fast-fail behavior. + *

* If you need the results of given stages, prefer below methods: - *

    + *
      *
    • {@link #allResultsOfFastFail(CompletionStage[])} *
    • {@link #allTupleOfFastFail(CompletionStage, CompletionStage)} / * {@link #allTupleOfFastFail(CompletionStage, CompletionStage, CompletionStage, CompletionStage, CompletionStage)} * (provided overloaded methods with 2~5 input) - *
+ * *

- * This method is the same as {@link #allOf(CompletionStage[])} except for the fast-fail behavior. + * If you need the successful results of given stages in the given time, prefer below methods: + *

    + *
  • {@link #mostResultsOfSuccess(long, TimeUnit, Object, CompletionStage[])} + *
  • {@link #mostResultsOfSuccess(Executor, long, TimeUnit, Object, CompletionStage[])} + *
  • {@link #mostTupleOfSuccess(long, TimeUnit, CompletionStage, CompletionStage)} + *
  • {@link #mostTupleOfSuccess(Executor, long, TimeUnit, CompletionStage, CompletionStage)} + *
  • {@link #mostTupleOfSuccess(long, TimeUnit, CompletionStage, CompletionStage, CompletionStage, CompletionStage, CompletionStage)} + *
  • {@link #mostTupleOfSuccess(Executor, long, TimeUnit, CompletionStage, CompletionStage, CompletionStage, CompletionStage, CompletionStage)} + *
* * @param cfs the stages * @return a new CompletableFuture that is successful when all the given stages success * @throws NullPointerException if the array or any of its elements are {@code null} * @see #allResultsOfFastFail(CompletionStage[]) * @see #allTupleOfFastFail(CompletionStage, CompletionStage) - * @see #allTupleOfFastFail(CompletionStage, CompletionStage, CompletionStage) - * @see #allTupleOfFastFail(CompletionStage, CompletionStage, CompletionStage, CompletionStage) * @see #allTupleOfFastFail(CompletionStage, CompletionStage, CompletionStage, CompletionStage, CompletionStage) + * @see #mostResultsOfSuccess(long, TimeUnit, Object, CompletionStage[]) + * @see #mostResultsOfSuccess(Executor, long, TimeUnit, Object, CompletionStage[]) + * @see #mostTupleOfSuccess(long, TimeUnit, CompletionStage, CompletionStage) + * @see #mostTupleOfSuccess(Executor, long, TimeUnit, CompletionStage, CompletionStage) + * @see #mostTupleOfSuccess(long, TimeUnit, CompletionStage, CompletionStage, CompletionStage, CompletionStage, CompletionStage) + * @see #mostTupleOfSuccess(Executor, long, TimeUnit, CompletionStage, CompletionStage, CompletionStage, CompletionStage, CompletionStage) * @see #allOf(CompletionStage[]) */ @Contract(pure = true) public static CompletableFuture allOfFastFail(CompletionStage... cfs) { requireCfsAndEleNonNull(cfs); - final int size = cfs.length; - if (size == 0) return completedFuture(null); + final int len = cfs.length; + if (len == 0) return completedFuture(null); // Defensive copy input cf to non-minimal-stage instance for SINGLE input in order to ensure that // the returned cf is not minimal-stage CF instance(UnsupportedOperationException) - if (size == 1) return toNonMinCfCopy(cfs[0]).thenApply(unused -> null); + if (len == 1) return toNonMinCfCopy(cfs[0]).thenApply(unused -> null); - final CompletableFuture[] successOrBeIncomplete = new CompletableFuture[size]; + final CompletableFuture[] successOrBeIncomplete = new CompletableFuture[len]; // NOTE: fill ONE MORE element of failedOrBeIncomplete LATER - final CompletableFuture[] failedOrBeIncomplete = new CompletableFuture[size + 1]; + final CompletableFuture[] failedOrBeIncomplete = new CompletableFuture[len + 1]; fill(cfs, successOrBeIncomplete, failedOrBeIncomplete); // NOTE: fill the ONE MORE element of failedOrBeIncomplete HERE: // a cf that is successful when all given cfs success, otherwise be incomplete - failedOrBeIncomplete[size] = CompletableFuture.allOf(successOrBeIncomplete); + failedOrBeIncomplete[len] = CompletableFuture.allOf(successOrBeIncomplete); CompletableFuture ret = CompletableFuture.anyOf(failedOrBeIncomplete); return f_cast(ret); @@ -181,20 +209,20 @@ public static CompletableFuture allOfFastFail(CompletionStage... cfs) { @SafeVarargs public static CompletableFuture> allResultsOfFastFail(CompletionStage... cfs) { requireCfsAndEleNonNull(cfs); - final int size = cfs.length; - if (size == 0) return completedFuture(arrayList()); + final int len = cfs.length; + if (len == 0) return completedFuture(arrayList()); // Defensive copy input cf to non-minimal-stage instance(toNonMinCfCopy) for SINGLE input // in order to ensure that the returned cf is not minimal-stage CF instance(UnsupportedOperationException) - if (size == 1) return toNonMinCfCopy(cfs[0]).thenApply(CompletableFutureUtils::arrayList); + if (len == 1) return toNonMinCfCopy(cfs[0]).thenApply(CompletableFutureUtils::arrayList); - final CompletableFuture[] successOrBeIncomplete = new CompletableFuture[size]; + final CompletableFuture[] successOrBeIncomplete = new CompletableFuture[len]; // NOTE: fill ONE MORE element of failedOrBeIncomplete LATER - final CompletableFuture[] failedOrBeIncomplete = new CompletableFuture[size + 1]; + final CompletableFuture[] failedOrBeIncomplete = new CompletableFuture[len + 1]; fill(cfs, successOrBeIncomplete, failedOrBeIncomplete); // NOTE: fill the ONE MORE element of failedOrBeIncomplete HERE: // a cf that is successful when all given cfs success, otherwise be incomplete - failedOrBeIncomplete[size] = allResultsOf(successOrBeIncomplete); + failedOrBeIncomplete[len] = allResultsOf(successOrBeIncomplete); CompletableFuture ret = CompletableFuture.anyOf(failedOrBeIncomplete); return f_cast(ret); @@ -244,7 +272,7 @@ public static CompletableFuture> mostResultsOfSuccess( if (cfs.length == 0) return completedFuture(arrayList()); if (cfs.length == 1) { // Defensive copy input cf to non-minimal-stage instance in order to - // 1. avoid writing it by `completeOnTimeout` and is able to read its result(`getSuccessNow`) + // 1. avoid writing it by `cffuOrTimeout` and is able to read its result(`getSuccessNow`) // 2. ensure that the returned cf is not minimal-stage CF instance(UnsupportedOperationException) final CompletableFuture f = toNonMinCfCopy(requireNonNull(cfs[0], "cf1 is null")); return cffuOrTimeout(f, executorWhenTimeout, timeout, unit) @@ -394,7 +422,7 @@ private static CompletableFuture toNonMinCfCopy(CompletionStage cf) { + private static boolean isMinStageCf(CompletableFuture cf) { return "java.util.concurrent.CompletableFuture$MinimalStage".equals(cf.getClass().getName()); } @@ -452,21 +480,21 @@ public static CompletableFuture anyOf(CompletionStage... cfs @SafeVarargs public static CompletableFuture anyOfSuccess(CompletionStage... cfs) { requireCfsAndEleNonNull(cfs); - final int size = cfs.length; - if (size == 0) return failedFuture(new NoCfsProvidedException()); + final int len = cfs.length; + if (len == 0) return failedFuture(new NoCfsProvidedException()); // Defensive copy input cf to non-minimal-stage instance for SINGLE input in order to ensure that // 1. avoid writing the input cf unexpectedly it by caller code // 2. the returned cf is not minimal-stage CF instance(UnsupportedOperationException) - if (size == 1) return toNonMinCfCopy(cfs[0]); + if (len == 1) return toNonMinCfCopy(cfs[0]); // NOTE: fill ONE MORE element of successOrBeIncompleteCfs LATER - final CompletableFuture[] successOrBeIncomplete = new CompletableFuture[size + 1]; - final CompletableFuture[] failedOrBeIncomplete = new CompletableFuture[size]; + final CompletableFuture[] successOrBeIncomplete = new CompletableFuture[len + 1]; + final CompletableFuture[] failedOrBeIncomplete = new CompletableFuture[len]; fill(cfs, successOrBeIncomplete, failedOrBeIncomplete); // NOTE: fill the ONE MORE element of successOrBeIncompleteCfs HERE // a cf that is failed when all given cfs fail, otherwise be incomplete - successOrBeIncomplete[size] = CompletableFuture.allOf(failedOrBeIncomplete); + successOrBeIncomplete[len] = CompletableFuture.allOf(failedOrBeIncomplete); CompletableFuture ret = CompletableFuture.anyOf(successOrBeIncomplete); return f_cast(ret); @@ -625,11 +653,11 @@ private static CompletableFuture allTupleOf0(CompletionStage[] css, bo @SuppressWarnings("unchecked") private static T tupleOf0(Object... elements) { - final int length = elements.length; + final int len = elements.length; final Object ret; - if (length == 2) ret = Tuple2.of(elements[0], elements[1]); - else if (length == 3) ret = Tuple3.of(elements[0], elements[1], elements[2]); - else if (length == 4) ret = Tuple4.of(elements[0], elements[1], elements[2], elements[3]); + if (len == 2) ret = Tuple2.of(elements[0], elements[1]); + else if (len == 3) ret = Tuple3.of(elements[0], elements[1], elements[2]); + else if (len == 4) ret = Tuple4.of(elements[0], elements[1], elements[2], elements[3]); else ret = Tuple5.of(elements[0], elements[1], elements[2], elements[3], elements[4]); return (T) ret; }