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 1658298b..963836db 100644 --- a/cffu-core/src/main/java/io/foldright/cffu/CompletableFutureUtils.java +++ b/cffu-core/src/main/java/io/foldright/cffu/CompletableFutureUtils.java @@ -654,7 +654,7 @@ public static CompletableFuture> mostResultsOfSuccess( // MUST be non-minimal-stage CF instances in order to read results(`getSuccessNow`), // otherwise UnsupportedOperationException - final CompletableFuture[] cfArray = f_toNonMinCfArray(cfs); + final CompletableFuture[] cfArray = toNonMinCfArray(cfs); return cffuCompleteOnTimeout(CompletableFuture.allOf(cfArray), null, executorWhenTimeout, timeout, unit) .handle((unused, ex) -> arrayList(MGetSuccessNow0(valueIfNotSuccess, cfArray))); } @@ -821,7 +821,7 @@ private static CompletableFuture[] createResultSetterCfs(CompletionSta final CompletableFuture[] resultSetterCfs = new CompletableFuture[result.length]; for (int i = 0; i < result.length; i++) { final int index = i; - resultSetterCfs[index] = toCf(css[index]).thenAccept(v -> result[index] = v); + resultSetterCfs[index] = f_toCf(css[index]).thenAccept(v -> result[index] = v); } return resultSetterCfs; } @@ -831,7 +831,7 @@ private static void fill(CompletionStage[] css, CompletableFuture[] failedOrBeIncomplete) { final CompletableFuture incomplete = new CompletableFuture<>(); for (int i = 0; i < css.length; i++) { - final CompletableFuture f = toCf(css[i]); + final CompletableFuture f = f_toCf(css[i]); successOrBeIncomplete[i] = f.handle((v, ex) -> ex == null ? f : incomplete).thenCompose(x -> x); failedOrBeIncomplete[i] = f.handle((v, ex) -> ex == null ? incomplete : f).thenCompose(x -> x); } @@ -848,17 +848,18 @@ private static CompletableFuture f_cast(CompletableFuture cf) { /** * Force converts {@link CompletionStage} array to {@link CompletableFuture} array, - * IGNORE the compile-time type check. + * reuse cf instance as many as possible. This method is NOT type safe! + * More info see method {@link #f_toCf(CompletionStage)}. */ private static CompletableFuture[] f_toCfArray(CompletionStage[] stages) { - return toCfArray0(stages, CompletableFutureUtils::toCf); + return toCfArray0(stages, CompletableFutureUtils::f_toCf); } /** - * Force converts {@link CompletionStage} array to {@link CompletableFuture} array, - * IGNORE the compile-time type check. + * Converts {@link CompletionStage} array to {@link CompletableFuture} array. + * More info see method {@link #toNonMinCf(CompletionStage)}. */ - private static CompletableFuture[] f_toNonMinCfArray(CompletionStage[] stages) { + private static CompletableFuture[] toNonMinCfArray(CompletionStage[] stages) { return toCfArray0(stages, CompletableFutureUtils::toNonMinCf); } @@ -875,14 +876,14 @@ private static CompletableFuture[] toCfArray0( } /** - * Converts CompletionStage to CompletableFuture, reuse cf instance as many as possible. + * Force converts CompletionStage to CompletableFuture, reuse cf instance as many as possible. *

- * CAUTION: because reused the CF instances, - * so the returned CF instances MUST NOT be written(e.g. {@link CompletableFuture#complete(Object)}). - * Otherwise, the caller should defensive copy instead of writing it directly. + * CAUTION: This method is NOT type safe! Because reused the CF instances, + * The returned cf may be a minimal-stage, MUST NOT be written (e.g. {@link CompletableFuture#complete(Object)}). + * Otherwise, the caller may trigger {@link UnsupportedOperationException}. */ @SuppressWarnings("unchecked") - private static CompletableFuture toCf(CompletionStage s) { + private static CompletableFuture f_toCf(CompletionStage s) { if (s instanceof CompletableFuture) return (CompletableFuture) s; else if (s instanceof Cffu) return ((Cffu) s).cffuUnwrap(); else return (CompletableFuture) s.toCompletableFuture(); @@ -892,24 +893,24 @@ private static CompletableFuture toCf(CompletionStage s) { * Converts CompletionStage to non-minimal-stage CompletableFuture, reuse cf instance as many as possible. *

* CAUTION: because reused the CF instances, - * so the returned CF instances MUST NOT be written(e.g. {@link CompletableFuture#complete(Object)}). + * so the returned CF instances should NOT be written(e.g. {@link CompletableFuture#complete(Object)}). * Otherwise, the caller should defensive copy instead of writing it directly. */ private static CompletableFuture toNonMinCf(CompletionStage s) { - final CompletableFuture f = toCf(s); + final CompletableFuture f = f_toCf(s); return isMinStageCf(f) ? f.toCompletableFuture() : f; } /** - * Converts CompletionStage to a non-minimal-stage CompletableFuture copy. + * Converts CompletionStage to a non-minimal-stage CompletableFuture copy. This method is type safe. *

- * NOTE: The return of {@code copy} methods + * Implemetation Note: The return of {@code copy} methods * ({@link #copy(CompletableFuture)}/{@link CompletableFuture#copy()}) on {@code minimal-stage} * is still a {@code minimal-stage}.
* e.g. {@code minimalCompletionStage().copy()}, {@code completedStage().copy()}. */ private static CompletableFuture toNonMinCfCopy(CompletionStage s) { - final CompletableFuture f = toCf(s); + final CompletableFuture f = f_toCf(s); return isMinStageCf(f) ? f.toCompletableFuture() : copy(f); } @@ -1318,7 +1319,7 @@ private static CompletableFuture mostTupleOfSuccess0( requireNonNull(unit, "unit is null"); // MUST be *Non-Minimal* CF instances in order to read results(`getSuccessNow`), // otherwise UnsupportedOperationException - final CompletableFuture[] cfArray = f_toNonMinCfArray(css); + final CompletableFuture[] cfArray = toNonMinCfArray(css); return cffuCompleteOnTimeout(CompletableFuture.allOf(cfArray), null, executorWhenTimeout, timeout, unit) .handle((unused, ex) -> tupleOf0(MGetSuccessNow0(null, cfArray))); }