Skip to content

Commit

Permalink
! update after release v1.0.0-Alpha7
Browse files Browse the repository at this point in the history
  • Loading branch information
oldratlee committed May 29, 2024
1 parent 077b4aa commit e4e07e9
Show file tree
Hide file tree
Showing 6 changed files with 79 additions and 81 deletions.
28 changes: 14 additions & 14 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
<a href="https://gitpod.io/#https://github.com/foldright/cffu"><img src="https://img.shields.io/badge/Gitpod-ready to code-339933?label=gitpod&logo=gitpod&logoColor=white" alt="gitpod: Ready to Code"></a>
</p>

👉 `cffu``CompletableFuture Fu` 🦝)是一个小小的[`CompletableFuture(CF)`](https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/util/concurrent/CompletableFuture.html)辅助增强库,提升`CF`使用体验并减少误用,期望在业务中更方便高效安全地使用`CF`
👉 `cffu``CompletableFuture Fu` 🦝)是一个小小的[`CompletableFuture(CF)`](https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/util/concurrent/CompletableFuture.html)辅助增强库,提升`CF`使用体验并减少误用,在业务中更方便高效安全地使用`CF`

欢迎 👏 💖

Expand Down Expand Up @@ -560,18 +560,18 @@ public class ConcurrencyStrategyDemo {
<dependency>
<groupId>io.foldright</groupId>
<artifactId>cffu</artifactId>
<version>1.0.0-Alpha6</version>
<version>1.0.0-Alpha7</version>
</dependency>
```
- For `Gradle` projects:

```groovy
// Gradle Kotlin DSL
implementation("io.foldright:cffu:1.0.0-Alpha6")
implementation("io.foldright:cffu:1.0.0-Alpha7")
```
```groovy
// Gradle Groovy DSL
implementation 'io.foldright:cffu:1.0.0-Alpha6'
implementation 'io.foldright:cffu:1.0.0-Alpha7'
```
- `cffu Kotlin`支持库:
- For `Maven` projects:
Expand All @@ -580,18 +580,18 @@ public class ConcurrencyStrategyDemo {
<dependency>
<groupId>io.foldright</groupId>
<artifactId>cffu-kotlin</artifactId>
<version>1.0.0-Alpha6</version>
<version>1.0.0-Alpha7</version>
</dependency>
```
- For `Gradle` projects:

```groovy
// Gradle Kotlin DSL
implementation("io.foldright:cffu-kotlin:1.0.0-Alpha6")
implementation("io.foldright:cffu-kotlin:1.0.0-Alpha7")
```
```groovy
// Gradle Groovy DSL
implementation 'io.foldright:cffu-kotlin:1.0.0-Alpha6'
implementation 'io.foldright:cffu-kotlin:1.0.0-Alpha7'
```
- `cffu bom`:
- For `Maven` projects:
Expand All @@ -600,7 +600,7 @@ public class ConcurrencyStrategyDemo {
<dependency>
<groupId>io.foldright</groupId>
<artifactId>cffu-bom</artifactId>
<version>1.0.0-Alpha6</version>
<version>1.0.0-Alpha7</version>
<type>pom</type>
<scope>import</scope>
</dependency>
Expand All @@ -609,11 +609,11 @@ public class ConcurrencyStrategyDemo {

```groovy
// Gradle Kotlin DSL
implementation(platform("io.foldright:cffu-bom:1.0.0-Alpha6"))
implementation(platform("io.foldright:cffu-bom:1.0.0-Alpha7"))
```
```groovy
// Gradle Groovy DSL
implementation platform('io.foldright:cffu-bom:1.0.0-Alpha6')
implementation platform('io.foldright:cffu-bom:1.0.0-Alpha7')
```
- [📌 `TransmittableThreadLocal(TTL)`](https://github.com/alibaba/transmittable-thread-local)的[`cffu executor wrapper SPI`实现](cffu-ttl-executor-wrapper):
- For `Maven` projects:
Expand All @@ -622,19 +622,19 @@ public class ConcurrencyStrategyDemo {
<dependency>
<groupId>io.foldright</groupId>
<artifactId>cffu-ttl-executor-wrapper</artifactId>
<version>1.0.0-Alpha6</version>
<version>1.0.0-Alpha7</version>
<scope>runtime</scope>
</dependency>
```
- For `Gradle` projects:

```groovy
// Gradle Kotlin DSL
runtimeOnly("io.foldright:cffu-ttl-executor-wrapper:1.0.0-Alpha6")
runtimeOnly("io.foldright:cffu-ttl-executor-wrapper:1.0.0-Alpha7")
```
```groovy
// Gradle Groovy DSL
runtimeOnly 'io.foldright:cffu-ttl-executor-wrapper:1.0.0-Alpha6'
runtimeOnly 'io.foldright:cffu-ttl-executor-wrapper:1.0.0-Alpha7'
```

# 📚 更多资料
Expand All @@ -645,7 +645,7 @@ public class ConcurrencyStrategyDemo {
- [`CompletableFuture` Guide](docs/completable-future-guide.md)
- 完备说明`CompletableFuture`的使用方式
- 给出 最佳实践建议 与 使用陷阱注意
- 期望在业务中,更有效安全地使用`CompletableFuture`
- 在业务中,更有效安全地使用`CompletableFuture`

# 👋 关于库名

Expand Down
29 changes: 13 additions & 16 deletions cffu-core/src/main/java/io/foldright/cffu/Cffu.java
Original file line number Diff line number Diff line change
Expand Up @@ -42,12 +42,12 @@ public final class Cffu<T> implements Future<T>, CompletionStage<T> {

@Contract(pure = true)
private <U> Cffu<U> reset0(CompletableFuture<U> cf) {
return new Cffu<>(this.fac, this.isMinimalStage, cf);
return new Cffu<>(fac, isMinimalStage, cf);
}

@Contract(pure = true)
private <U> Cffu<U> resetToMin(CompletableFuture<U> cf) {
return new Cffu<>(this.fac, true, cf);
return new Cffu<>(fac, true, cf);
}

////////////////////////////////////////////////////////////////////////////////
Expand Down Expand Up @@ -947,8 +947,7 @@ public Cffu<T> exceptionallyAsync(Function<Throwable, ? extends T> fn, Executor
* <p>
* Uses {@link #defaultExecutor()} as {@code executorWhenTimeout}.
*
* @param timeout how long to wait before completing exceptionally
* with a TimeoutException, in units of {@code unit}
* @param timeout how long to wait before completing exceptionally with a TimeoutException, in units of {@code unit}
* @param unit a {@code TimeUnit} determining how to interpret the {@code timeout} parameter
* @return the new Cffu
* @see #orTimeout(Executor, long, TimeUnit)
Expand All @@ -962,8 +961,7 @@ public Cffu<T> orTimeout(long timeout, TimeUnit unit) {
* if not otherwise completed before the given timeout.
*
* @param executorWhenTimeout the async executor when triggered by timeout
* @param timeout how long to wait before completing exceptionally
* with a TimeoutException, in units of {@code unit}
* @param timeout how long to wait before completing exceptionally with a TimeoutException, in units of {@code unit}
* @param unit a {@code TimeUnit} determining how to interpret the {@code timeout} parameter
* @return the new Cffu
*/
Expand All @@ -976,22 +974,22 @@ public Cffu<T> orTimeout(Executor executorWhenTimeout, long timeout, TimeUnit un
* Exceptionally completes given Cffu with a {@link TimeoutException}
* if not otherwise completed before the given timeout.
* <p>
* <strong>CAUTION:<br></strong> This method is <strong>UNSAFE</strong>!
* <strong>CAUTION:</strong> This method is <strong>UNSAFE</strong>!
* <p>
* When triggered by timeout, the subsequent non-async actions of the dependent cfs
* are performed in the <strong>SINGLE thread builtin executor</strong>
* of CompletableFuture for delay executions (including timeout function).
* of CompletableFuture for delay execution(including timeout function).
* So the long-running subsequent non-async actions lead to the CompletableFuture dysfunction
* (including delay execution and timeout).
* <p>
* <strong>Strong recommend</strong> using the safe methods {@link #orTimeout(long, TimeUnit)}
* <strong>Strong recommend</strong> using the safe method {@link #orTimeout(long, TimeUnit)}
* instead of this method.
* <p>
* Unless all subsequent actions of dependent cfs is ensured executing async
* (aka. the dependent cfs is created by async methods), using this method
* is one less thread switch of task execution when triggered by timeout.
*
* @param timeout how long to wait before completing normally with the given value, in units of {@code unit}
* @param timeout how long to wait before completing exceptionally with a TimeoutException, in units of {@code unit}
* @param unit a {@code TimeUnit} determining how to interpret the {@code timeout} parameter
* @return this Cffu
* @see #orTimeout(long, TimeUnit)
Expand Down Expand Up @@ -1033,15 +1031,15 @@ public Cffu<T> completeOnTimeout(@Nullable T value, Executor executorWhenTimeout
/**
* Completes given Cffu with the given value if not otherwise completed before the given timeout.
* <p>
* <strong>CAUTION:<br></strong> This method is <strong>UNSAFE</strong>!
* <strong>CAUTION:</strong> This method is <strong>UNSAFE</strong>!
* <p>
* When triggered by timeout, the subsequent non-async actions of the dependent cfs
* are performed in the <strong>SINGLE thread builtin executor</strong>
* of CompletableFuture for delay executions (including timeout function).
* of CompletableFuture for delay execution (including timeout function).
* So the long-running subsequent non-async actions lead to the CompletableFuture dysfunction
* (including delay execution and timeout).
* <p>
* <strong>Strong recommend</strong> using the safe methods {@link #completeOnTimeout(Object, long, TimeUnit)}
* <strong>Strong recommend</strong> using the safe method {@link #completeOnTimeout(Object, long, TimeUnit)}
* instead of this method.
* <p>
* Unless all subsequent actions of dependent cfs is ensured executing async
Expand Down Expand Up @@ -1844,7 +1842,7 @@ public CompletionStage<T> minimalCompletionStage() {
*/
@Contract(pure = true)
public Cffu<T> resetCffuFactory(CffuFactory cffuFactory) {
return new Cffu<>(cffuFactory, this.isMinimalStage, this.cf);
return new Cffu<>(cffuFactory, isMinimalStage, cf);
}

/**
Expand Down Expand Up @@ -2059,8 +2057,7 @@ public <U> Cffu<U> newIncompleteFuture() {
@Contract(pure = true)
@Override
public String toString() {
return this.getClass().getSimpleName() + "@" + Integer.toHexString(System.identityHashCode(this))
+ "(" + cf + ")";
return getClass().getSimpleName() + "@" + Integer.toHexString(System.identityHashCode(this)) + "(" + cf + ")";
}

private void checkMinimalStage() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

import static io.foldright.cffu.Delayer.IS_IN_CF_DELAYER_THREAD;
import static java.util.Objects.requireNonNull;
import static java.util.concurrent.CompletableFuture.completedFuture;


/**
Expand Down Expand Up @@ -89,7 +90,7 @@ public static CompletableFuture<Void> allOf(CompletionStage<?>... cfs) {
public static <T> CompletableFuture<List<T>> allResultsOf(CompletionStage<? extends T>... cfs) {
requireCfsAndEleNonNull(cfs);
final int size = cfs.length;
if (size == 0) return CompletableFuture.completedFuture(arrayList());
if (size == 0) return completedFuture(arrayList());
if (size == 1) return csToListCf(cfs[0]);

final Object[] result = new Object[size];
Expand Down Expand Up @@ -133,7 +134,7 @@ public static <T> CompletableFuture<List<T>> allResultsOf(CompletionStage<? exte
public static CompletableFuture<Void> allOfFastFail(CompletionStage<?>... cfs) {
requireCfsAndEleNonNull(cfs);
final int size = cfs.length;
if (size == 0) return CompletableFuture.completedFuture(null);
if (size == 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 non-minimal-stage CF instance(UnsupportedOperationException)
if (size == 1) return toNonMinCfCopy(cfs[0]).thenApply(unused -> null);
Expand Down Expand Up @@ -175,7 +176,7 @@ public static CompletableFuture<Void> allOfFastFail(CompletionStage<?>... cfs) {
public static <T> CompletableFuture<List<T>> allResultsOfFastFail(CompletionStage<? extends T>... cfs) {
requireCfsAndEleNonNull(cfs);
final int size = cfs.length;
if (size == 0) return CompletableFuture.completedFuture(arrayList());
if (size == 0) return completedFuture(arrayList());
if (size == 1) return csToListCf(cfs[0]);

final CompletableFuture<?>[] successOrBeIncomplete = new CompletableFuture[size];
Expand Down Expand Up @@ -231,7 +232,7 @@ public static <T> CompletableFuture<List<T>> mostResultsOfSuccess(
requireNonNull(unit, "unit is null");
requireCfsAndEleNonNull(cfs);

if (cfs.length == 0) return CompletableFuture.completedFuture(arrayList());
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`)
Expand Down Expand Up @@ -664,7 +665,7 @@ public static <T1, T2> CompletableFuture<Tuple2<T1, T2>> mostTupleOfSuccess(
public static <T1, T2> CompletableFuture<Tuple2<T1, T2>> mostTupleOfSuccess(
Executor executorWhenTimeout, long timeout, TimeUnit unit,
CompletionStage<? extends T1> cf1, CompletionStage<? extends T2> cf2) {
return mostTupleOfSuccess0(timeout, unit, executorWhenTimeout, requireCfsAndEleNonNull(cf1, cf2));
return mostTupleOfSuccess0(executorWhenTimeout, timeout, unit, requireCfsAndEleNonNull(cf1, cf2));
}

/**
Expand Down Expand Up @@ -703,7 +704,7 @@ public static <T1, T2, T3> CompletableFuture<Tuple3<T1, T2, T3>> mostTupleOfSucc
public static <T1, T2, T3> CompletableFuture<Tuple3<T1, T2, T3>> mostTupleOfSuccess(
Executor executorWhenTimeout, long timeout, TimeUnit unit,
CompletionStage<? extends T1> cf1, CompletionStage<? extends T2> cf2, CompletionStage<? extends T3> cf3) {
return mostTupleOfSuccess0(timeout, unit, executorWhenTimeout, requireCfsAndEleNonNull(cf1, cf2, cf3));
return mostTupleOfSuccess0(executorWhenTimeout, timeout, unit, requireCfsAndEleNonNull(cf1, cf2, cf3));
}

/**
Expand Down Expand Up @@ -744,7 +745,7 @@ public static <T1, T2, T3, T4> CompletableFuture<Tuple4<T1, T2, T3, T4>> mostTup
Executor executorWhenTimeout, long timeout, TimeUnit unit,
CompletionStage<? extends T1> cf1, CompletionStage<? extends T2> cf2,
CompletionStage<? extends T3> cf3, CompletionStage<? extends T4> cf4) {
return mostTupleOfSuccess0(timeout, unit, executorWhenTimeout, requireCfsAndEleNonNull(cf1, cf2, cf3, cf4));
return mostTupleOfSuccess0(executorWhenTimeout, timeout, unit, requireCfsAndEleNonNull(cf1, cf2, cf3, cf4));
}

/**
Expand Down Expand Up @@ -785,11 +786,11 @@ public static <T1, T2, T3, T4, T5> CompletableFuture<Tuple5<T1, T2, T3, T4, T5>>
Executor executorWhenTimeout, long timeout, TimeUnit unit,
CompletionStage<? extends T1> cf1, CompletionStage<? extends T2> cf2, CompletionStage<? extends T3> cf3,
CompletionStage<? extends T4> cf4, CompletionStage<? extends T5> cf5) {
return mostTupleOfSuccess0(timeout, unit, executorWhenTimeout, requireCfsAndEleNonNull(cf1, cf2, cf3, cf4, cf5));
return mostTupleOfSuccess0(executorWhenTimeout, timeout, unit, requireCfsAndEleNonNull(cf1, cf2, cf3, cf4, cf5));
}

private static <T> CompletableFuture<T> mostTupleOfSuccess0(
long timeout, TimeUnit unit, Executor executorWhenTimeout, CompletionStage<?>[] css) {
Executor executorWhenTimeout, long timeout, TimeUnit unit, CompletionStage<?>[] css) {
requireNonNull(unit, "unit is null");
// MUST be *Non-Minimal* CF instances in order to read results(`getSuccessNow`),
// otherwise UnsupportedOperationException
Expand Down Expand Up @@ -1354,7 +1355,7 @@ public static <T> CompletionStage<T> completedStage(@Nullable T value) {
if (IS_JAVA9_PLUS) {
return CompletableFuture.completedStage(value);
}
return CompletableFuture.completedFuture(value);
return completedFuture(value);
}

/**
Expand Down Expand Up @@ -1494,16 +1495,16 @@ public static <C extends CompletableFuture<?>> C cffuOrTimeout(
* Exceptionally completes given CompletableFuture with a {@link TimeoutException}
* if not otherwise completed before the given timeout.
* <p>
* <strong>CAUTION:<br></strong> This method and {@link CompletableFuture#orTimeout(long, TimeUnit)}
* <strong>CAUTION:</strong> This method and {@link CompletableFuture#orTimeout(long, TimeUnit)}
* is <strong>UNSAFE</strong>!
* <p>
* When triggered by timeout, the subsequent non-async actions of the dependent CompletableFutures
* are performed in the <strong>SINGLE thread builtin executor</strong>
* of CompletableFuture for delay executions (including timeout function).
* of CompletableFuture for delay execution (including timeout function).
* So the long-running subsequent non-async actions lead to the CompletableFuture dysfunction
* (including delay execution and timeout).
* <p>
* <strong>Strong recommend</strong> using the safe methods {@link #cffuOrTimeout(CompletableFuture, long, TimeUnit)}
* <strong>Strong recommend</strong> using the safe method {@link #cffuOrTimeout(CompletableFuture, long, TimeUnit)}
* instead of this method and {@link CompletableFuture#orTimeout(long, TimeUnit)}.
* <p>
* Unless all subsequent actions of dependent CompletableFutures is ensured executing async
Expand Down Expand Up @@ -1563,16 +1564,16 @@ C cffuCompleteOnTimeout(C cf, @Nullable T value, Executor executorWhenTimeout, l
/**
* Completes given CompletableFuture with the given value if not otherwise completed before the given timeout.
* <p>
* <strong>CAUTION:<br></strong> This method and {@link CompletableFuture#completeOnTimeout(Object, long, TimeUnit)}
* <strong>CAUTION:</strong> This method and {@link CompletableFuture#completeOnTimeout(Object, long, TimeUnit)}
* is <strong>UNSAFE</strong>!
* <p>
* When triggered by timeout, the subsequent non-async actions of the dependent CompletableFutures
* are performed in the <strong>SINGLE thread builtin executor</strong>
* of CompletableFuture for delay executions (including timeout function).
* of CompletableFuture for delay execution (including timeout function).
* So the long-running subsequent non-async actions lead to the CompletableFuture dysfunction
* (including delay execution and timeout).
* <p>
* <strong>Strong recommend</strong> using the safe methods {@link #cffuCompleteOnTimeout(CompletableFuture, Object, long, TimeUnit)}
* <strong>Strong recommend</strong> using the safe method {@link #cffuCompleteOnTimeout(CompletableFuture, Object, long, TimeUnit)}
* instead of this method and {@link CompletableFuture#completeOnTimeout(Object, long, TimeUnit)}.
* <p>
* Unless all subsequent actions of dependent CompletableFutures is ensured executing async
Expand Down Expand Up @@ -1601,12 +1602,12 @@ C completeOnTimeout(C cf, @Nullable T value, long timeout, TimeUnit unit) {
}

@SuppressWarnings("unchecked")
private static <T, C extends CompletionStage<? extends T>>
C hopAsyncIf(C cf, BooleanSupplier condition, Executor ayncExecutor) {
private static <C extends CompletionStage<?>>
C hopAsyncIf(C cf, BooleanSupplier condition, Executor asyncExecutor) {
return (C) cf.handle((r, ex) -> condition.getAsBoolean()
? cf.handleAsync((r1, ex1) -> cf, ayncExecutor).thenCompose(x -> (CompletionStage<T>) x)
? cf.handleAsync((r1, ex1) -> cf, asyncExecutor).thenCompose(x -> (CompletionStage<?>) x)
: cf
).thenCompose(x -> (CompletionStage<T>) x);
).thenCompose(x -> x);
}

//# Advanced methods of CompletionStage
Expand Down Expand Up @@ -2071,7 +2072,7 @@ private static class AsyncPoolHolder {
private static final Executor ASYNC_POOL = _asyncPool0();

private static Executor _asyncPool0() {
if (IS_JAVA9_PLUS) return CompletableFuture.completedFuture(null).defaultExecutor();
if (IS_JAVA9_PLUS) return completedFuture(null).defaultExecutor();
if (USE_COMMON_POOL) return ForkJoinPool.commonPool();
return new ThreadPerTaskExecutor();
}
Expand Down Expand Up @@ -2099,7 +2100,7 @@ private static Executor _asyncPool0() {
}
IS_JAVA9_PLUS = b;

final CompletableFuture<Integer> cf = CompletableFuture.completedFuture(42);
final CompletableFuture<Integer> cf = completedFuture(42);
try {
// `exceptionallyCompose` is the new method of CompletableFuture since java 12
cf.exceptionallyCompose(v -> cf);
Expand Down
Loading

0 comments on commit e4e07e9

Please sign in to comment.