use of io.smallrye.mutiny.subscription.UniSubscriber in project smallrye-mutiny by smallrye.
the class UniSerializedSubscriberTest method testRogueUpstreamSendingFailureBeforeSubscription.
@Test
public void testRogueUpstreamSendingFailureBeforeSubscription() {
AbstractUni<Integer> rogue = new AbstractUni<Integer>() {
@Override
public void subscribe(UniSubscriber<? super Integer> subscriber) {
subscriber.onFailure(new IOException("boom"));
subscriber.onSubscribe(() -> {
});
}
};
UniAssertSubscriber<Integer> subscriber = UniAssertSubscriber.create();
UniSerializedSubscriber.subscribe(rogue, subscriber);
subscriber.assertSubscribed().assertFailedWith(IOException.class, "boom").assertSignalsReceivedInOrder();
}
use of io.smallrye.mutiny.subscription.UniSubscriber in project smallrye-mutiny by smallrye.
the class UniSerializedSubscriberTest method testDroppedExceptionsWhenOnFailureCalledMultipleTimes.
@Test
public void testDroppedExceptionsWhenOnFailureCalledMultipleTimes() {
AtomicReference<Throwable> received = new AtomicReference<>();
AtomicReference<Throwable> captured = new AtomicReference<>();
Infrastructure.setDroppedExceptionHandler(captured::set);
AtomicReference<UniSubscriber<? super Integer>> sub = new AtomicReference<>();
AbstractUni<Integer> uni = new AbstractUni<Integer>() {
@Override
public void subscribe(UniSubscriber<? super Integer> subscriber) {
sub.set(subscriber);
}
};
UniSerializedSubscriber.subscribe(uni, new UniSubscriber<Integer>() {
@Override
public Context context() {
return Context.empty();
}
@Override
public void onSubscribe(UniSubscription subscription) {
// Do nothing
}
@Override
public void onItem(Integer item) {
// Do nothing
}
@Override
public void onFailure(Throwable failure) {
received.set(failure);
}
});
sub.get().onSubscribe(mock(UniSubscription.class));
sub.get().onFailure(new IOException("I/O"));
assertThat(captured.get()).isNull();
assertThat(received.get()).isInstanceOf(IOException.class).hasMessageContaining("I/O");
sub.get().onFailure(new IllegalStateException("boom"));
assertThat(captured.get()).isNotNull().isInstanceOf(IllegalStateException.class).hasMessageContaining("boom");
assertThat(received.get()).isInstanceOf(IOException.class).hasMessageContaining("I/O");
}
use of io.smallrye.mutiny.subscription.UniSubscriber in project smallrye-mutiny by smallrye.
the class UniOrCombination method subscribe.
@SuppressWarnings({ "unchecked", "rawtypes" })
@Override
public void subscribe(UniSubscriber<? super T> subscriber) {
if (challengers.isEmpty()) {
subscriber.onSubscribe(EmptyUniSubscription.DONE);
subscriber.onItem(null);
return;
}
if (challengers.size() == 1) {
// Just subscribe to the first and unique uni.
Uni<? super T> uni = challengers.get(0);
AbstractUni.subscribe(uni, (UniSubscriber) subscriber);
return;
}
// Barrier - once set to {@code true} the signals are ignored
AtomicBoolean completedOrCancelled = new AtomicBoolean();
List<CompletableFuture<? super T>> futures = new ArrayList<>();
challengers.forEach(uni -> {
CompletableFuture<? super T> future = uni.subscribe().asCompletionStage(subscriber.context());
futures.add(future);
});
// Do not call unSubscribe until we get all the futures.
// But at the same time we can't start resolving as we didn't give a subscription to the subscriber
// yet.
subscriber.onSubscribe(() -> {
if (completedOrCancelled.compareAndSet(false, true)) {
// Cancel all
futures.forEach(cf -> cf.cancel(false));
}
});
// Once the subscription has been given, start resolving
futures.forEach(future -> future.whenComplete((res, fail) -> {
if (completedOrCancelled.compareAndSet(false, true)) {
// Cancel other
futures.forEach(cf -> {
if (cf != future) {
cf.cancel(false);
}
});
if (fail != null) {
subscriber.onFailure(fail);
} else {
subscriber.onItem((T) res);
}
}
}));
}
use of io.smallrye.mutiny.subscription.UniSubscriber in project smallrye-mutiny by smallrye.
the class UniBlockingAwait method await.
public static <T> T await(Uni<T> upstream, Duration duration, Context context) {
nonNull(upstream, "upstream");
validate(duration);
if (!Infrastructure.canCallerThreadBeBlocked()) {
throw new IllegalStateException("The current thread cannot be blocked: " + Thread.currentThread().getName());
}
CountDownLatch latch = new CountDownLatch(1);
AtomicReference<T> reference = new AtomicReference<>();
AtomicReference<Throwable> referenceToFailure = new AtomicReference<>();
UniSubscriber<T> subscriber = new UniSubscriber<T>() {
@Override
public Context context() {
return (context != null) ? context : Context.empty();
}
@Override
public void onSubscribe(UniSubscription subscription) {
// Do nothing.
}
@Override
public void onItem(T item) {
reference.set(item);
latch.countDown();
}
@Override
public void onFailure(Throwable failure) {
referenceToFailure.compareAndSet(null, failure);
latch.countDown();
}
};
AbstractUni.subscribe(upstream, subscriber);
try {
if (duration != null) {
if (!latch.await(duration.toMillis(), TimeUnit.MILLISECONDS)) {
referenceToFailure.compareAndSet(null, new TimeoutException());
}
} else {
latch.await();
}
} catch (InterruptedException e) {
referenceToFailure.compareAndSet(null, e);
Thread.currentThread().interrupt();
}
Throwable throwable = referenceToFailure.get();
if (throwable != null) {
if (throwable instanceof RuntimeException) {
throw (RuntimeException) throwable;
}
throw new CompletionException(throwable);
} else {
return reference.get();
}
}
use of io.smallrye.mutiny.subscription.UniSubscriber in project smallrye-mutiny by smallrye.
the class AbstractUni method subscribe.
/**
* Encapsulates subscription to slightly optimize the AbstractUni case.
*
* In the case of AbstractUni, it avoid creating the UniSubscribe group instance.
*
* @param upstream the upstream, must not be {@code null} (not checked)
* @param subscriber the subscriber, must not be {@code null} (not checked)
* @param <T> the type of item
*/
@SuppressWarnings("unchecked")
public static <T> void subscribe(Uni<? extends T> upstream, UniSubscriber<? super T> subscriber) {
if (upstream instanceof AbstractUni) {
AbstractUni abstractUni = (AbstractUni) upstream;
UniSubscriber actualSubscriber = Infrastructure.onUniSubscription(upstream, subscriber);
abstractUni.subscribe(actualSubscriber);
} else {
upstream.subscribe().withSubscriber(subscriber);
}
}
Aggregations