Skip to content

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
oldratlee committed Apr 23, 2024
1 parent e69f255 commit a0e00e7
Show file tree
Hide file tree
Showing 7 changed files with 76 additions and 194 deletions.
16 changes: 8 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -73,15 +73,15 @@
- `cffuAllOf`/`allOfWithResult`方法:返回多个`CF`的结果,而不是无返回结果`Void``allOf`
- `cffuCombine`/`combine`方法:返回多个`CF`不同类型的结果,而不是同一类型(`cffuAllOf`/`allOfWithResult`
- 更高效灵活的并发执行策略,如
- `cffuAllOfFastFail`/`allOfFastFail`方法:有`CF`失败时快速返回,而不再等待所有`CF`运行完成(`allOf`
- `cffuAnyOfSuccess`/`anyOfSuccess`方法:返回首个成功的`CF`结果,而不是首个完成(但可能失败)的`CF``anyOf`
- `allOfFastFail`方法:有`CF`失败时快速返回,而不再等待所有`CF`运行完成(`allOf`
- `anyOfSuccess`方法:返回首个成功的`CF`结果,而不是首个完成(但可能失败)的`CF``anyOf`
- 更安全的使用方式,如
- 支持设置缺省的业务线程池(`CffuFactoryBuilder#newCffuFactoryBuilder(executor)`方法)
- `cffuJoin(timeout, unit)`方法:支持超时的`join`的方法
- 支持禁止强制篡改(`CffuFactoryBuilder#forbidObtrudeMethods`方法)
- 在类方法附加完善的代码质量注解(如`@NonNull``@Nullable``@CheckReturnValue``@Contract`等),在编码时`IDE`能尽早提示出问题
- 💪 **已有功能的增强**,如
- `cffuAnyOf`/`anyOfWithType`方法:返回类型是`T`(类型安全),而不是返回`Object``anyOf`
- `anyOf`方法:返回类型是`T`(类型安全),而不是返回`Object``CompletableFuture#anyOf()`
-**`Backport`支持`Java 8`**`Java 9+`高版本的所有`CF`新功能在`Java 8`等低`Java`版本直接可用,如
- 超时控制:`orTimeout`/`completeOnTimeout`方法
- 延迟执行:`delayedExecutor`方法
Expand Down Expand Up @@ -182,7 +182,7 @@ public class CffuDemo {
final Cffu<Integer> combined = longTaskA.thenCombine(longTaskB, Integer::sum)
.orTimeout(1500, TimeUnit.MILLISECONDS);
System.out.println("combined result: " + combined.get());
final Cffu<Integer> anyOfSuccess = cffuFactory.cffuAnyOfSuccess(longTaskC, longFailedTask);
final Cffu<Integer> anyOfSuccess = cffuFactory.anyOfSuccess(longTaskC, longFailedTask);
System.out.println("anyOfSuccess result: " + anyOfSuccess.get());
}
}
Expand Down Expand Up @@ -418,7 +418,7 @@ public class DefaultExecutorSettingForCffu {
- `allOf`/`allOfFastFail`两者都是,只有当所有的输入`CF`都成功时,才返回成功结果
- `CompletableFuture``anyOf`方法返回首个完成的`CF`(不会等待后续没有完成的`CF`,赛马模式);即使首个完成的`CF`是失败的,也会返回这个失败的`CF`结果。
- 对于业务逻辑来说,会希望赛马模式返回首个成功的`CF`结果,而不是首个完成但失败的`CF`
- `cffu`提供了相应的`cffuAnyOfSuccess`/`anyOfSuccess`方法
- `cffu`提供了相应的`anyOfSuccess`方法
- `anyOfSuccess`只有当所有的输入`CF`都失败时,才返回失败结果

> 📔 关于多个`CF`的并发执行策略,可以看看`JavaScript`规范[`Promise Concurrency`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise#promise_concurrency);在`JavaScript`中,`Promise`即对应`CompletableFuture`
Expand All @@ -444,7 +444,7 @@ public class ConcurrencyStrategyDemo {
public static void main(String[] args) throws Exception {
////////////////////////////////////////////////////////////////////////
// CffuFactory#cffuAllOfFastFail / allOfFastFail
// CffuFactory#cffuAnyOfSuccess / anyOfSuccess
// CffuFactory#anyOfSuccess
////////////////////////////////////////////////////////////////////////
final Cffu<Integer> successAfterLongTime = cffuFactory.supplyAsync(() -> {
sleep(3000); // sleep LONG time
Expand All @@ -461,7 +461,7 @@ public class ConcurrencyStrategyDemo {
// Result type is Object!
Cffu<Object> cffuAny = cffuFactory.anyOfSuccess(successAfterLongTime, failed);
System.out.println(cffuAny.get());
Cffu<Integer> anyOfSuccess = cffuFactory.cffuAnyOfSuccess(successAfterLongTime, failed);
Cffu<Integer> anyOfSuccess = cffuFactory.anyOfSuccess(successAfterLongTime, failed);
System.out.println(anyOfSuccess.get());

////////////////////////////////////////////////////////////////////////
Expand Down Expand Up @@ -519,7 +519,7 @@ public class ConcurrencyStrategyDemo {

`CompletableFuture.anyOf`方法返回类型是`Object`,丢失具体类型,不够类型安全,使用时需要转型也不方便。

`cffu`提供了`cffuAnyOf`/`anyOfWithType`方法,返回类型是`T`(类型安全),而不是返回`Object``anyOf`)。
`cffu`提供了`anyOf`/`anyOf`方法,返回类型是`T`(类型安全),而不是返回`Object``CompletableFuture#anyOf()`)。

这个新方法使用简单类似,不附代码示例。

Expand Down
139 changes: 15 additions & 124 deletions cffu-core/src/main/java/io/foldright/cffu/CffuFactory.java
Original file line number Diff line number Diff line change
Expand Up @@ -443,41 +443,35 @@ public Cffu<Void> allOfFastFail() {
* Otherwise, if it completed exceptionally, the returned Cffu also does so,
* with a CompletionException holding this exception as its cause.<br>
* If no Cffus are provided, returns an incomplete Cffu.
* <p>
* prefer {@link #cffuAnyOf(Cffu[])} method if the given Cffus have same result type,
* because {@link #cffuAnyOf(Cffu[])} return type {@code T} instead of type {@code Object}, more type safe.
*
* @param cfs the Cffus
* @return a new Cffu that is completed with the result
* or exception from any of the given Cffus when one completes
* @throws NullPointerException if the array or any of its elements are {@code null}
* @see #cffuAnyOf(Cffu[])
* @see CompletableFuture#anyOf(CompletableFuture[])
*/
@Contract(pure = true)
@SuppressWarnings("unchecked")
public Cffu<Object> anyOf(Cffu<?>... cfs) {
return anyOf(toCompletableFutureArray((Cffu<Object>[]) cfs));
@SafeVarargs
public final <T> Cffu<T> anyOf(Cffu<? extends T>... cfs) {
return anyOf(toCompletableFutureArray((Cffu<T>[]) cfs));
}

/**
* Same as {@link #anyOf(Cffu[])} with overloaded argument type {@link CompletableFuture}.
* <p>
* prefer {@link #cffuAnyOf(CompletableFuture[])} method if the given Cffus have same result type,
* because {@link #cffuAnyOf(CompletableFuture[])} return type {@code T}
* instead of type {@code Object}, more type safe.
*
* @param cfs the CompletableFutures
* @return a new Cffu that is completed with the result
* or exception from any of the given CompletableFutures when one completes
* @throws NullPointerException if the array or any of its elements are {@code null}
* @see #cffuAnyOf(CompletableFuture[])
* @see #anyOf(Cffu[])
* @see CompletableFuture#anyOf(CompletableFuture[])
*/
@Contract(pure = true)
public Cffu<Object> anyOf(CompletableFuture<?>... cfs) {
return new0(CompletableFuture.anyOf(cfs));
@SuppressWarnings("unchecked")
@SafeVarargs
public final <T> Cffu<T> anyOf(CompletableFuture<? extends T>... cfs) {
return (Cffu<T>) new0(CompletableFuture.anyOf(cfs));
}

/**
Expand All @@ -488,7 +482,7 @@ public Cffu<Object> anyOf(CompletableFuture<?>... cfs) {
* @see #anyOf(CompletableFuture[])
*/
@Contract(pure = true)
public Cffu<Object> anyOf() {
public <T> Cffu<T> anyOf() {
return newIncompleteCffu();
}

Expand All @@ -503,11 +497,11 @@ public Cffu<Object> anyOf() {
* @param cfs the Cffus
* @return a new Cffu
* @throws NullPointerException if the array or any of its elements are {@code null}
* @see #cffuAnyOf(Cffu[])
*/
@SuppressWarnings({"unchecked", "rawtypes"})
public Cffu<Object> anyOfSuccess(Cffu<?>... cfs) {
return anyOfSuccess(toCompletableFutureArray((Cffu[]) cfs));
@SafeVarargs
public final <T> Cffu<T> anyOfSuccess(Cffu<? extends T>... cfs) {
return (Cffu<T>) anyOfSuccess(toCompletableFutureArray((Cffu[]) cfs));
}

/**
Expand All @@ -521,21 +515,17 @@ public Cffu<Object> anyOfSuccess(Cffu<?>... cfs) {
* @param cfs the CompletableFutures
* @return a new Cffu
* @throws NullPointerException if the array or any of its elements are {@code null}
* @see #cffuAnyOfSuccess(Cffu[])
* @see #cffuAnyOf(Cffu[])
*/
public Cffu<Object> anyOfSuccess(CompletableFuture<?>... cfs) {
@SafeVarargs
public final <T> Cffu<T> anyOfSuccess(CompletableFuture<? extends T>... cfs) {
return new0(CompletableFutureUtils.anyOfSuccess(cfs));
}

/**
* Provided this overloaded method just for resolving "cffuAnyOfSuccess is ambiguous" problem
* Provided this overloaded method just for resolving "anyOfSuccess is ambiguous" problem
* when call {@code anyOfSuccess} with empty arguments: {@code cffuFactory.anyOfSuccess()}.
*
* @see #cffuAnyOfSuccess(Cffu[])
* @see #cffuAnyOfSuccess(CompletableFuture[])
*/
public Cffu<Object> anyOfSuccess() {
public <T> Cffu<T> anyOfSuccess() {
return new0(CompletableFutureUtils.anyOfSuccess());
}

Expand Down Expand Up @@ -581,7 +571,6 @@ public Executor delayedExecutor(long delay, TimeUnit unit, Executor executor) {
// method name prefix with `cffu`
//
// - cffuAllOf
// - cffuAnyOf
////////////////////////////////////////////////////////////////////////////////

/**
Expand Down Expand Up @@ -694,104 +683,6 @@ public <T> Cffu<List<T>> cffuAllOfFastFail() {
return new0(CompletableFutureUtils.allResultsOfFastFail());
}

/**
* Returns a new Cffu that is completed when any of the given Cffus complete, with the same result.
* <p>
* Same as {@link #anyOf(Cffu[])}, but return result type is specified type instead of type {@code Object}.
*
* @param cfs the Cffus
* @return a new Cffu that is completed with the result
* or exception from any of the given Cffus when one completes
* @throws NullPointerException if the array or any of its elements are {@code null}
* @see #anyOf(Cffu[])
*/
@Contract(pure = true)
@SafeVarargs
@SuppressWarnings({"unchecked", "rawtypes"})
public final <T> Cffu<T> cffuAnyOf(Cffu<? extends T>... cfs) {
return cffuAnyOf(toCompletableFutureArray((Cffu[]) cfs));
}

/**
* Returns a new Cffu that is completed when any of the given CompletableFutures complete, with the same result.
* <p>
* Same as {@link #cffuAllOf(Cffu[])} with overloaded argument type {@link CompletableFuture}.
*
* @param cfs the CompletableFutures
* @return a new Cffu that is completed with the result
* or exception from any of the given CompletableFutures when one completes
* @throws NullPointerException if the array or any of its elements are {@code null}
* @see #cffuAnyOf(Cffu[])
*/
@Contract(pure = true)
@SafeVarargs
public final <T> Cffu<T> cffuAnyOf(CompletableFuture<? extends T>... cfs) {
return new0(CompletableFutureUtils.anyOf(cfs));
}

/**
* Provided this overloaded method just for resolving "cffuAnyOf is ambiguous" problem
* when call {@code cffuAnyOf} with empty arguments: {@code cffuFactory.cffuAnyOf()}.
*
* @see #cffuAnyOf(Cffu[])
* @see #cffuAnyOf(CompletableFuture[])
*/
@Contract(pure = true)
public <T> Cffu<T> cffuAnyOf() {
return newIncompleteCffu();
}

/**
* Returns a new Cffu that is successful when any of the given Cffus success,
* with the same result. Otherwise, all the given Cffus complete exceptionally,
* the returned Cffu also does so, with a CompletionException holding
* an exception from any of the given Cffu as its cause. If no Cffu are provided,
* returns a new Cffu that is already completed exceptionally
* with a CompletionException holding a {@link NoCfsProvidedException} as its cause.
*
* @param cfs the Cffus
* @return a new Cffu
* @throws NullPointerException if the array or any of its elements are {@code null}
* @see #cffuAnyOf(Cffu[])
*/
@SafeVarargs
@SuppressWarnings({"rawtypes", "unchecked"})
public final <T> Cffu<T> cffuAnyOfSuccess(Cffu<? extends T>... cfs) {
return cffuAnyOfSuccess(toCompletableFutureArray((Cffu[]) cfs));
}

/**
* Returns a new Cffu that is successful when any of the given CompletableFutures success,
* with the same result. Otherwise, all the given CompletableFutures complete exceptionally,
* the returned Cffu also does so, with a CompletionException holding
* an exception from any of the given CompletableFutures as its cause. If no CompletableFutures are provided,
* returns a new Cffu that is already completed exceptionally
* with a CompletionException holding a {@link NoCfsProvidedException} as its cause.
* <p>
* Same as {@link #cffuAnyOfSuccess(Cffu[])} with overloaded argument type {@link CompletableFuture}.
*
* @param cfs the CompletableFutures
* @return a new Cffu
* @throws NullPointerException if the array or any of its elements are {@code null}
* @see #cffuAnyOfSuccess(Cffu[])
* @see #cffuAnyOf(Cffu[])
*/
@SafeVarargs
public final <T> Cffu<T> cffuAnyOfSuccess(CompletableFuture<? extends T>... cfs) {
return new0(CompletableFutureUtils.anyOfSuccess(cfs));
}

/**
* Provided this overloaded method just for resolving "cffuAnyOfSuccess is ambiguous" problem
* when call {@code cffuAnyOfSuccess} with empty arguments: {@code cffuFactory.cffuAnyOfSuccess()}.
*
* @see #cffuAnyOfSuccess(Cffu[])
* @see #cffuAnyOfSuccess(CompletableFuture[])
*/
public <T> Cffu<T> cffuAnyOfSuccess() {
return new0(CompletableFutureUtils.anyOfSuccess());
}

////////////////////////////////////////////////////////////////////////////////
//# New type-safe cffuCombine Factory Methods
// support 2~5 input arguments, method name prefix with `cffu`
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,6 @@
* Exception indicates that NO cfs({@link Cffu} / {@link CompletableFuture}) are provided
* for methods require cf arguments.
*
* @see CffuFactory#cffuAnyOfSuccess(Cffu[])
* @see CffuFactory#cffuAnyOfSuccess(CompletableFuture[])
* @see CffuFactory#anyOfSuccess(Cffu[])
* @see CffuFactory#anyOfSuccess(CompletableFuture[])
* @see CompletableFutureUtils#anyOfSuccess(CompletableFuture[])
Expand Down
Loading

0 comments on commit a0e00e7

Please sign in to comment.