diff --git a/common/reactive/src/main/java/io/helidon/common/reactive/Single.java b/common/reactive/src/main/java/io/helidon/common/reactive/Single.java index 21994ef47..298b03a7f 100644 --- a/common/reactive/src/main/java/io/helidon/common/reactive/Single.java +++ b/common/reactive/src/main/java/io/helidon/common/reactive/Single.java @@ -228,7 +228,7 @@ public interface Single extends Subscribable, CompletionStage, Awaitabl * @return Single */ static Single never() { - return SingleNever.instance(); + return new SingleNever(); } /** diff --git a/common/reactive/src/main/java/io/helidon/common/reactive/SingleNever.java b/common/reactive/src/main/java/io/helidon/common/reactive/SingleNever.java index ccf305605..8c1a1e1c5 100644 --- a/common/reactive/src/main/java/io/helidon/common/reactive/SingleNever.java +++ b/common/reactive/src/main/java/io/helidon/common/reactive/SingleNever.java @@ -21,24 +21,16 @@ import java.util.concurrent.Flow.Subscriber; * Implementation of {@link Single} that never invokes * {@link Subscriber#onComplete()} or * {@link Subscriber#onError(java.lang.Throwable)}. + * + * @param item type */ -final class SingleNever extends CompletionSingle { +final class SingleNever extends CompletionSingle { - /** - * Singleton instance. - */ - private static final SingleNever INSTANCE = new SingleNever(); - - private SingleNever() { + SingleNever() { } @Override - public void subscribe(Subscriber actual) { + public void subscribe(Subscriber actual) { actual.onSubscribe(EmptySubscription.INSTANCE); } - - @SuppressWarnings("unchecked") - static Single instance() { - return (Single) INSTANCE; - } } diff --git a/common/reactive/src/test/java/io/helidon/common/reactive/SingleTest.java b/common/reactive/src/test/java/io/helidon/common/reactive/SingleTest.java index 33f6b0c71..c1f1e8cd7 100644 --- a/common/reactive/src/test/java/io/helidon/common/reactive/SingleTest.java +++ b/common/reactive/src/test/java/io/helidon/common/reactive/SingleTest.java @@ -157,6 +157,22 @@ public class SingleTest { assertThat(subscriber.getItems(), is(empty())); } + @Test + public void testNeverIsNotSingleton() throws InterruptedException, TimeoutException, ExecutionException { + CompletableFuture cf1 = new CompletableFuture<>(); + CompletableFuture cf2 = new CompletableFuture<>(); + Single never1 = Single.never(); + Single never2 = Single.never(); + + never1.onCancel(() -> cf1.complete(null)); + never2.onCancel(() -> cf2.complete(null)); + never1.cancel(); + + cf1.get(100, TimeUnit.MILLISECONDS); + assertThat("First Single.never should be cancelled!", cf1.isDone()); + assertThat("Other Single.never should NOT be cancelled!", !cf2.isDone()); + } + @Test public void testMap() { SingleTestSubscriber subscriber = new SingleTestSubscriber<>();