From 4026d9bc9d576227aa84ae93b471a91be1ed298f Mon Sep 17 00:00:00 2001 From: Andrea Cavalli Date: Thu, 27 Aug 2020 16:56:54 +0200 Subject: [PATCH] Added more CompletableFuture utils --- .../future/CompletableFutureUtils.java | 107 +++++++++++++++++- .../concurrency/future/FutureLockUtils.java | 49 ++------ .../functional/BiCompletableFunction.java | 7 ++ .../functional/CompletableFunction.java | 7 ++ .../functional/IOCompletableFunction.java | 8 ++ .../commonutils/functional/IOFunction.java | 2 +- .../functional/TriCompletableFunction.java | 7 ++ 7 files changed, 142 insertions(+), 45 deletions(-) create mode 100644 src/main/java/org/warp/commonutils/functional/BiCompletableFunction.java create mode 100644 src/main/java/org/warp/commonutils/functional/CompletableFunction.java create mode 100644 src/main/java/org/warp/commonutils/functional/IOCompletableFunction.java create mode 100644 src/main/java/org/warp/commonutils/functional/TriCompletableFunction.java diff --git a/src/main/java/org/warp/commonutils/concurrency/future/CompletableFutureUtils.java b/src/main/java/org/warp/commonutils/concurrency/future/CompletableFutureUtils.java index f9c4268..193b8e3 100644 --- a/src/main/java/org/warp/commonutils/concurrency/future/CompletableFutureUtils.java +++ b/src/main/java/org/warp/commonutils/concurrency/future/CompletableFutureUtils.java @@ -12,16 +12,107 @@ import java.util.Set; import java.util.TreeSet; import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletionStage; +import java.util.concurrent.Executor; import java.util.concurrent.ExecutorService; import java.util.function.Consumer; import java.util.function.Function; import java.util.function.Supplier; import java.util.stream.Collectors; +import org.warp.commonutils.functional.BiCompletableFunction; +import org.warp.commonutils.functional.CompletableFunction; +import org.warp.commonutils.functional.IOCompletableFunction; +import org.warp.commonutils.functional.IOSupplier; +import org.warp.commonutils.functional.TriCompletableFunction; import org.warp.commonutils.type.FloatPriorityQueue; import org.warp.commonutils.type.ScoredValue; public class CompletableFutureUtils { + /** + * Safely get a CompletableFuture or a FailedFuture + */ + public static CompletableFuture getCompletableFuture(Supplier> completableFutureSupplier) { + CompletableFuture cf; + try { + cf = completableFutureSupplier.get(); + } catch (Exception ex) { + cf = CompletableFuture.failedFuture(ex); + } + return cf; + } + + /** + * Safely get a CompletableFuture or a FailedFuture + */ + public static CompletableFuture getCompletableFuture(CompletableFunction completableFutureFunction, F value) { + return getCompletableFuture(() -> completableFutureFunction.apply(value)); + } + + /** + * Safely get a CompletableFuture or a FailedFuture + */ + public static CompletableFuture getCompletableFutureSupply(CompletableFunction completableFutureFunction, Supplier valueSupplier) { + return getCompletableFuture(() -> completableFutureFunction.apply(valueSupplier.get())); + } + + /** + * Safely get a CompletableFuture or a FailedFuture + */ + public static CompletableFuture getCompletableFuture(BiCompletableFunction completableFutureFunction, F1 value1, F2 value2) { + return getCompletableFuture(() -> completableFutureFunction.apply(value1, value2)); + } + + /** + * Safely get a CompletableFuture or a FailedFuture + */ + public static CompletableFuture getCompletableFutureSupply(BiCompletableFunction completableFutureFunction, Supplier value1Supplier, Supplier value2Supplier) { + return getCompletableFuture(() -> completableFutureFunction.apply(value1Supplier.get(), value2Supplier.get())); + } + + /** + * Safely get a CompletableFuture or a FailedFuture + */ + public static CompletableFuture getCompletableFuture(TriCompletableFunction completableFutureFunction, F1 value1, F2 value2, F3 value3) { + return getCompletableFuture(() -> completableFutureFunction.apply(value1, value2, value3)); + } + + /** + * Safely get a CompletableFuture or a FailedFuture + */ + public static CompletableFuture getCompletableFutureSupply(TriCompletableFunction completableFutureFunction, Supplier value1Supplier, Supplier value2Supplier, Supplier value3Supplier) { + return getCompletableFuture(() -> completableFutureFunction.apply(value1Supplier.get(), value2Supplier.get(), value3Supplier.get())); + } + + //// + + + /** + * Safely get a CompletableFuture or a FailedFuture + */ + public static CompletableFuture getCompletableFutureIO(IOSupplier> completableFutureSupplier) { + CompletableFuture cf; + try { + cf = completableFutureSupplier.get(); + } catch (Exception ex) { + cf = CompletableFuture.failedFuture(ex); + } + return cf; + } + + /** + * Safely get a CompletableFuture or a FailedFuture + */ + public static CompletableFuture getCompletableFutureIO(IOCompletableFunction completableFutureFunction, F value) { + return getCompletableFutureIO(() -> completableFutureFunction.apply(value)); + } + + /** + * Safely get a CompletableFuture or a FailedFuture + */ + public static CompletableFuture getCompletableFutureIOSupply(IOCompletableFunction completableFutureFunction, IOSupplier valueSupplier) { + return getCompletableFutureIO(() -> completableFutureFunction.apply(valueSupplier.get())); + } + /** * Aggregate multiple {@link CompletableFuture} lists into a single {@link CompletableFuture} list * @@ -244,12 +335,12 @@ public class CompletableFutureUtils { futureList.join().parallelStream().map(CompletableFuture::join).forEach(consumer); } + /** + * Use CompletableFutureUtils.getCompletableFuture(supplier); + */ + @Deprecated public static CompletableFuture catchUncheckedExceptions(Supplier> supplier) { - try { - return supplier.get(); - } catch (Exception exception) { - return CompletableFuture.failedFuture(exception); - } + return getCompletableFuture(supplier); } public static CompletableFuture runSequence(Collection> collection) { @@ -307,4 +398,10 @@ public class CompletableFutureUtils { } return result; } + + public static CompletableFuture composeAsync( + Supplier> supp, + Executor executor) { + return CompletableFuture.completedFuture(null).thenComposeAsync((_x) -> supp.get(), executor); + } } diff --git a/src/main/java/org/warp/commonutils/concurrency/future/FutureLockUtils.java b/src/main/java/org/warp/commonutils/concurrency/future/FutureLockUtils.java index 6a9b25d..18f84ae 100644 --- a/src/main/java/org/warp/commonutils/concurrency/future/FutureLockUtils.java +++ b/src/main/java/org/warp/commonutils/concurrency/future/FutureLockUtils.java @@ -1,6 +1,5 @@ package org.warp.commonutils.concurrency.future; -import java.io.IOException; import java.util.concurrent.CompletableFuture; import java.util.concurrent.locks.StampedLock; import java.util.function.Supplier; @@ -17,18 +16,11 @@ public class FutureLockUtils { } else { lockValue = 0; } - try { - return r.get().whenComplete((x, y) -> { - if (lock != null) { - lock.unlockRead(lockValue); - } - }); - } catch (Throwable ex) { + return CompletableFutureUtils.getCompletableFuture(r).whenComplete((result, err) -> { if (lock != null) { lock.unlockRead(lockValue); } - throw ex; - } + }); } public static CompletableFuture writeLock(@Nullable StampedLock lock, @NotNull Supplier> r) { @@ -38,59 +30,38 @@ public class FutureLockUtils { } else { lockValue = 0; } - try { - return r.get().whenComplete((x, y) -> { - if (lock != null) { - lock.unlockWrite(lockValue); - } - }); - } catch (Throwable ex) { + return CompletableFutureUtils.getCompletableFuture(r).whenComplete((result, err) -> { if (lock != null) { lock.unlockWrite(lockValue); } - throw ex; - } + }); } - public static CompletableFuture readLockIO(@Nullable StampedLock lock, @NotNull IOSupplier> r) throws IOException { + public static CompletableFuture readLockIO(@Nullable StampedLock lock, @NotNull IOSupplier> r) { long lockValue; if (lock != null) { lockValue = lock.readLock(); } else { lockValue = 0; } - try { - return r.get().whenComplete((x, y) -> { - if (lock != null) { - lock.unlockRead(lockValue); - } - }); - } catch (Throwable ex) { + return CompletableFutureUtils.getCompletableFutureIO(r).whenComplete((result, err) -> { if (lock != null) { lock.unlockRead(lockValue); } - throw ex; - } + }); } - public static CompletableFuture writeLockIO(@Nullable StampedLock lock, @NotNull IOSupplier> r) throws IOException { + public static CompletableFuture writeLockIO(@Nullable StampedLock lock, @NotNull IOSupplier> r) { long lockValue; if (lock != null) { lockValue = lock.writeLock(); } else { lockValue = 0; } - try { - return r.get().whenComplete((x, y) -> { - if (lock != null) { - lock.unlockWrite(lockValue); - } - }); - } catch (Throwable ex) { + return CompletableFutureUtils.getCompletableFutureIO(r).whenComplete((result, err) -> { if (lock != null) { lock.unlockWrite(lockValue); } - throw ex; - } + }); } } diff --git a/src/main/java/org/warp/commonutils/functional/BiCompletableFunction.java b/src/main/java/org/warp/commonutils/functional/BiCompletableFunction.java new file mode 100644 index 0000000..d59cb5d --- /dev/null +++ b/src/main/java/org/warp/commonutils/functional/BiCompletableFunction.java @@ -0,0 +1,7 @@ +package org.warp.commonutils.functional; + +import java.util.concurrent.CompletableFuture; + +public interface BiCompletableFunction { + CompletableFuture apply(T1 value1, T2 value2); +} diff --git a/src/main/java/org/warp/commonutils/functional/CompletableFunction.java b/src/main/java/org/warp/commonutils/functional/CompletableFunction.java new file mode 100644 index 0000000..691c433 --- /dev/null +++ b/src/main/java/org/warp/commonutils/functional/CompletableFunction.java @@ -0,0 +1,7 @@ +package org.warp.commonutils.functional; + +import java.util.concurrent.CompletableFuture; + +public interface CompletableFunction { + CompletableFuture apply(T value); +} diff --git a/src/main/java/org/warp/commonutils/functional/IOCompletableFunction.java b/src/main/java/org/warp/commonutils/functional/IOCompletableFunction.java new file mode 100644 index 0000000..e040a3a --- /dev/null +++ b/src/main/java/org/warp/commonutils/functional/IOCompletableFunction.java @@ -0,0 +1,8 @@ +package org.warp.commonutils.functional; + +import java.io.IOException; +import java.util.concurrent.CompletableFuture; + +public interface IOCompletableFunction { + CompletableFuture apply(T value) throws IOException; +} diff --git a/src/main/java/org/warp/commonutils/functional/IOFunction.java b/src/main/java/org/warp/commonutils/functional/IOFunction.java index 3790aa2..e5704c3 100644 --- a/src/main/java/org/warp/commonutils/functional/IOFunction.java +++ b/src/main/java/org/warp/commonutils/functional/IOFunction.java @@ -4,5 +4,5 @@ import java.io.IOException; public interface IOFunction { - U run(T data) throws IOException; + U apply(T data) throws IOException; } diff --git a/src/main/java/org/warp/commonutils/functional/TriCompletableFunction.java b/src/main/java/org/warp/commonutils/functional/TriCompletableFunction.java new file mode 100644 index 0000000..fa9b7d2 --- /dev/null +++ b/src/main/java/org/warp/commonutils/functional/TriCompletableFunction.java @@ -0,0 +1,7 @@ +package org.warp.commonutils.functional; + +import java.util.concurrent.CompletableFuture; + +public interface TriCompletableFunction { + CompletableFuture apply(T1 value1, T2 value2, T3 value3); +}