From c447ab59a56435564cf6f8b1e0623c0d85af4052 Mon Sep 17 00:00:00 2001 From: Julien Ponge Date: Wed, 20 Nov 2024 16:23:12 +0100 Subject: [PATCH] fix!(Uni): align the Uni::eventually operators to onTermination() semantics The Uni::eventually(Runnable) operator had been previously moved from onItemOrFailure() to onTermination() semantics so as to handle cancellation on top of already handling items and failures. This aligns the `eventually(Supplier>)` variant with its `eventually(Runnable)` counterpart. Fixes #1742. BREAKING CHANGE: this may break code bases where onItemOrFailure() semantics were correctly assumed and cancellation was handled separately. --- documentation/docs/guides/shortcut-methods.md | 24 +++++++++---------- .../src/main/java/io/smallrye/mutiny/Uni.java | 10 ++++---- 2 files changed, 18 insertions(+), 16 deletions(-) diff --git a/documentation/docs/guides/shortcut-methods.md b/documentation/docs/guides/shortcut-methods.md index a818bdfa1..020089e47 100644 --- a/documentation/docs/guides/shortcut-methods.md +++ b/documentation/docs/guides/shortcut-methods.md @@ -28,16 +28,16 @@ This is useful to execute an asynchronous action without modifying incoming item The following table lists the available shortcuts available by the `Uni` class: -| Shortcut | Equivalent | -|----------------------------------------------------------|-----------------------------------------------------------------------------------------------------| -| `uni.map(x -> y)` | `uni.onItem().transform(x -> y)` | -| `uni.flatMap(x -> uni2)` | `uni.onItem().transformToUni(x -> uni2)` | -| `uni.chain(x -> uni2)` | `uni.onItem().transformToUni(x -> uni2)` | -| `uni.invoke(x -> System.out.println(x))` | `uni.onItem().invoke(x -> System.out.println(x))` | -| `uni.call(x -> uni2)` | `uni.onItem().call(x -> uni2)` | -| `uni.eventually(() -> System.out.println("eventually"))` | `uni.onItemOrFailure().invoke((ignoredItem, ignoredException) -> System.out.println("eventually"))` | -| `uni.eventually(() -> uni2)` | `uni.onItemOrFailure().call((ignoredItem, ignoredException) -> uni2)` | -| `uni.replaceWith(x)` | `uni.onItem().transform(ignored -> x)` | -| `uni.replaceWith(uni2)` | `uni.onItem().transformToUni(ignored -> uni2)` | -| `uni.replaceIfNullWith(x)` | `uni.onItem().ifNull().continueWith(x)` | +| Shortcut | Equivalent | +|----------------------------------------------------------|--------------------------------------------------------------------------------------| +| `uni.map(x -> y)` | `uni.onItem().transform(x -> y)` | +| `uni.flatMap(x -> uni2)` | `uni.onItem().transformToUni(x -> uni2)` | +| `uni.chain(x -> uni2)` | `uni.onItem().transformToUni(x -> uni2)` | +| `uni.invoke(x -> System.out.println(x))` | `uni.onItem().invoke(x -> System.out.println(x))` | +| `uni.call(x -> uni2)` | `uni.onItem().call(x -> uni2)` | +| `uni.eventually(() -> System.out.println("eventually"))` | `uni.onTermination().invoke(() -> System.out.println("eventually"))` | +| `uni.eventually(() -> uni2)` | `uni.onTermination().call((ignoredItem, ignoredError, ignoredCancellation) -> uni2)` | +| `uni.replaceWith(x)` | `uni.onItem().transform(ignored -> x)` | +| `uni.replaceWith(uni2)` | `uni.onItem().transformToUni(ignored -> uni2)` | +| `uni.replaceIfNullWith(x)` | `uni.onItem().ifNull().continueWith(x)` | diff --git a/implementation/src/main/java/io/smallrye/mutiny/Uni.java b/implementation/src/main/java/io/smallrye/mutiny/Uni.java index 9a5c68391..2a7fc6ea2 100644 --- a/implementation/src/main/java/io/smallrye/mutiny/Uni.java +++ b/implementation/src/main/java/io/smallrye/mutiny/Uni.java @@ -13,6 +13,7 @@ import io.smallrye.mutiny.subscription.UniEmitter; import io.smallrye.mutiny.subscription.UniSubscriber; import io.smallrye.mutiny.subscription.UniSubscription; +import io.smallrye.mutiny.tuples.Functions; /** * A {@link Uni} represents a lazy asynchronous action. It follows the subscription pattern, meaning that the action @@ -551,7 +552,8 @@ default Uni eventually(Runnable action) { } /** - * When this {@link Uni} emits an item or a failure, invoke a {@link Uni} supplier then invoke the supplied {@link Uni}. + * When this {@link Uni} emits an item, a failure or is being cancelled, invoke a {@link Uni} supplier then invoke the + * supplied {@link Uni}. * When the supplied {@link Uni} emits an item then it is ignored, and when it emits a failure it is reported. *

* This is equivalent to a {@code finally} block in Java. @@ -566,8 +568,8 @@ default Uni eventually(Runnable action) { * } * *

- * This method is a shortcut for {@link UniOnItemOrFailure#call(BiFunction)}: - * {@code onItemOrFailure().call((item, err) -> supplier.get())} + * This method is a shortcut for {@link UniOnTerminate#call(Functions.Function3)}: + * {@code onTermination().call((item, err, cancelled) -> actual.get())} * * @param supplier a {@link Uni} supplier, cannot be {@code null} and cannot return {@code null}. * @param the type of the item @@ -577,7 +579,7 @@ default Uni eventually(Runnable action) { @CheckReturnValue default Uni eventually(Supplier> supplier) { Supplier> actual = nonNull(supplier, "supplier"); - return onItemOrFailure().call((item, err) -> actual.get()); + return onTermination().call((item, err, cancelled) -> actual.get()); } /**