Search in sources :

Example 1 with UniSubscriber

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();
}
Also used : UniSubscriber(io.smallrye.mutiny.subscription.UniSubscriber) IOException(java.io.IOException) RepeatedTest(org.junit.jupiter.api.RepeatedTest) Test(org.junit.jupiter.api.Test)

Example 2 with UniSubscriber

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");
}
Also used : Context(io.smallrye.mutiny.Context) AtomicReference(java.util.concurrent.atomic.AtomicReference) UniSubscription(io.smallrye.mutiny.subscription.UniSubscription) IOException(java.io.IOException) UniSubscriber(io.smallrye.mutiny.subscription.UniSubscriber) RepeatedTest(org.junit.jupiter.api.RepeatedTest) Test(org.junit.jupiter.api.Test)

Example 3 with UniSubscriber

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);
            }
        }
    }));
}
Also used : ParameterValidation.nonNull(io.smallrye.mutiny.helpers.ParameterValidation.nonNull) List(java.util.List) AbstractUni(io.smallrye.mutiny.operators.AbstractUni) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) CompletableFuture(java.util.concurrent.CompletableFuture) UniOperator(io.smallrye.mutiny.operators.UniOperator) EmptyUniSubscription(io.smallrye.mutiny.helpers.EmptyUniSubscription) UniSubscriber(io.smallrye.mutiny.subscription.UniSubscriber) ArrayList(java.util.ArrayList) Uni(io.smallrye.mutiny.Uni) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) CompletableFuture(java.util.concurrent.CompletableFuture) ArrayList(java.util.ArrayList)

Example 4 with UniSubscriber

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();
    }
}
Also used : AtomicReference(java.util.concurrent.atomic.AtomicReference) UniSubscription(io.smallrye.mutiny.subscription.UniSubscription) CountDownLatch(java.util.concurrent.CountDownLatch) CompletionException(java.util.concurrent.CompletionException) UniSubscriber(io.smallrye.mutiny.subscription.UniSubscriber) TimeoutException(io.smallrye.mutiny.TimeoutException)

Example 5 with UniSubscriber

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);
    }
}
Also used : UniSubscriber(io.smallrye.mutiny.subscription.UniSubscriber)

Aggregations

UniSubscriber (io.smallrye.mutiny.subscription.UniSubscriber)5 UniSubscription (io.smallrye.mutiny.subscription.UniSubscription)2 IOException (java.io.IOException)2 AtomicReference (java.util.concurrent.atomic.AtomicReference)2 RepeatedTest (org.junit.jupiter.api.RepeatedTest)2 Test (org.junit.jupiter.api.Test)2 Context (io.smallrye.mutiny.Context)1 TimeoutException (io.smallrye.mutiny.TimeoutException)1 Uni (io.smallrye.mutiny.Uni)1 EmptyUniSubscription (io.smallrye.mutiny.helpers.EmptyUniSubscription)1 ParameterValidation.nonNull (io.smallrye.mutiny.helpers.ParameterValidation.nonNull)1 AbstractUni (io.smallrye.mutiny.operators.AbstractUni)1 UniOperator (io.smallrye.mutiny.operators.UniOperator)1 ArrayList (java.util.ArrayList)1 List (java.util.List)1 CompletableFuture (java.util.concurrent.CompletableFuture)1 CompletionException (java.util.concurrent.CompletionException)1 CountDownLatch (java.util.concurrent.CountDownLatch)1 AtomicBoolean (java.util.concurrent.atomic.AtomicBoolean)1