Search in sources :

Example 21 with Subscriber

use of org.reactivestreams.Subscriber in project reactive-streams-jvm by reactive-streams.

the class PublisherVerification method required_spec109_mustIssueOnSubscribeForNonNullSubscriber.

// Verifies rule: https://github.com/reactive-streams/reactive-streams-jvm#1.9
@Override
@Test
public void required_spec109_mustIssueOnSubscribeForNonNullSubscriber() throws Throwable {
    activePublisherTest(0, false, new PublisherTestRun<T>() {

        @Override
        public void run(Publisher<T> pub) throws Throwable {
            final Latch onSubscribeLatch = new Latch(env);
            pub.subscribe(new Subscriber<T>() {

                @Override
                public void onError(Throwable cause) {
                    onSubscribeLatch.assertClosed("onSubscribe should be called prior to onError always");
                }

                @Override
                public void onSubscribe(Subscription subs) {
                    onSubscribeLatch.assertOpen("Only one onSubscribe call expected");
                    onSubscribeLatch.close();
                }

                @Override
                public void onNext(T elem) {
                    onSubscribeLatch.assertClosed("onSubscribe should be called prior to onNext always");
                }

                @Override
                public void onComplete() {
                    onSubscribeLatch.assertClosed("onSubscribe should be called prior to onComplete always");
                }
            });
            onSubscribeLatch.expectClose("Should have received onSubscribe");
            env.verifyNoAsyncErrorsNoDelay();
        }
    });
}
Also used : Subscriber(org.reactivestreams.Subscriber) ManualSubscriber(org.reactivestreams.tck.TestEnvironment.ManualSubscriber) Latch(org.reactivestreams.tck.TestEnvironment.Latch) Subscription(org.reactivestreams.Subscription) Override(java.lang.Override) Test(org.testng.annotations.Test) Override(java.lang.Override)

Example 22 with Subscriber

use of org.reactivestreams.Subscriber in project reactive-streams-jvm by reactive-streams.

the class PublisherVerificationTest method demandIgnoringAsynchronousPublisherVerification.

/**
   * Verification using a Publisher that publishes elements even with no demand available, from multiple threads (!).
   */
final PublisherVerification<Integer> demandIgnoringAsynchronousPublisherVerification(final ExecutorService signallersPool, final boolean swallowOnNextExceptions) {
    final AtomicInteger startedSignallingThreads = new AtomicInteger(0);
    final int maxSignallingThreads = 2;
    final AtomicBoolean concurrentAccessCaused = new AtomicBoolean(false);
    return new PublisherVerification<Integer>(newTestEnvironment()) {

        @Override
        public Publisher<Integer> createPublisher(long elements) {
            return new Publisher<Integer>() {

                @Override
                public void subscribe(final Subscriber<? super Integer> s) {
                    s.onSubscribe(new NoopSubscription() {

                        @Override
                        public void request(final long n) {
                            Runnable signalling = new Runnable() {

                                @Override
                                public void run() {
                                    for (long i = 0; i <= n; i++) {
                                        try {
                                            final long signal = i;
                                            signallersPool.execute(new Runnable() {

                                                @Override
                                                public void run() {
                                                    try {
                                                        s.onNext((int) signal);
                                                    } catch (Exception ex) {
                                                        if (!swallowOnNextExceptions) {
                                                            throw new RuntimeException("onNext threw an exception!", ex);
                                                        } else {
                                                        // yes, swallow the exception, we're not asserting and they'd just end up being logged (stdout),
                                                        // which we do not need in this specific PublisherVerificationTest
                                                        }
                                                    }
                                                }
                                            });
                                        } catch (Exception ex) {
                                            if (ex instanceof TestEnvironment.Latch.ExpectedOpenLatchException) {
                                                if (concurrentAccessCaused.compareAndSet(false, true)) {
                                                    throw new RuntimeException("Concurrent access detected", ex);
                                                } else {
                                                    // error signalled once already, stop more errors from propagating
                                                    return;
                                                }
                                            } else if (ex instanceof RejectedExecutionException) {
                                            // ignore - this may happen since one thread may have already gotten into a concurrent access
                                            // problem and initiated the pool's shutdown. It will then throw RejectedExecutionException.
                                            } else {
                                                if (concurrentAccessCaused.get()) {
                                                    return;
                                                } else {
                                                    throw new RuntimeException(ex);
                                                }
                                            }
                                        }
                                    }
                                }
                            };
                            // must be guarded like this in case a Subscriber triggers request() synchronously from it's onNext()
                            while (startedSignallingThreads.getAndAdd(1) < maxSignallingThreads) {
                                signallersPool.execute(signalling);
                            }
                        }
                    });
                }
            };
        }

        @Override
        public Publisher<Integer> createFailedPublisher() {
            return SKIP;
        }
    };
}
Also used : Publisher(org.reactivestreams.Publisher) TestException(org.reactivestreams.tck.support.TestException) RejectedExecutionException(java.util.concurrent.RejectedExecutionException) RejectedExecutionException(java.util.concurrent.RejectedExecutionException) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) Subscriber(org.reactivestreams.Subscriber)

Example 23 with Subscriber

use of org.reactivestreams.Subscriber in project reactive-streams-jvm by reactive-streams.

the class PublisherVerificationTest method required_spec317_mustNotSignalOnErrorWhenPendingAboveLongMaxValue_forSynchronousPublisher.

@Test
public void required_spec317_mustNotSignalOnErrorWhenPendingAboveLongMaxValue_forSynchronousPublisher() throws Throwable {
    final AtomicInteger sent = new AtomicInteger();
    customPublisherVerification(new Publisher<Integer>() {

        @Override
        public void subscribe(final Subscriber<? super Integer> downstream) {
            downstream.onSubscribe(new Subscription() {

                boolean started;

                boolean cancelled;

                @Override
                public void request(long n) {
                    if (!started) {
                        started = true;
                        while (!cancelled) {
                            downstream.onNext(sent.getAndIncrement());
                        }
                    }
                }

                @Override
                public void cancel() {
                    cancelled = true;
                }
            });
        }
    }).required_spec317_mustNotSignalOnErrorWhenPendingAboveLongMaxValue();
    // 11 due to the implementation of this particular TCK test (see impl)
    Assert.assertEquals(sent.get(), 11);
}
Also used : AtomicInteger(java.util.concurrent.atomic.AtomicInteger) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) Subscriber(org.reactivestreams.Subscriber) Publisher(org.reactivestreams.Publisher) Subscription(org.reactivestreams.Subscription) Test(org.testng.annotations.Test)

Example 24 with Subscriber

use of org.reactivestreams.Subscriber in project reactive-streams-jvm by reactive-streams.

the class PublisherVerificationTest method stochastic_spec103_mustSignalOnMethodsSequentially_shouldFailBy_concurrentlyAccessingOnNext.

@Test
public void stochastic_spec103_mustSignalOnMethodsSequentially_shouldFailBy_concurrentlyAccessingOnNext() throws Throwable {
    final AtomicInteger startedSignallingThreads = new AtomicInteger(0);
    // this is an arbitrary number, we just need "many threads" to try to force an concurrent access scenario
    final int maxSignallingThreads = 10;
    final ExecutorService signallersPool = Executors.newFixedThreadPool(maxSignallingThreads);
    final AtomicBoolean concurrentAccessCaused = new AtomicBoolean(false);
    // highly specialised threadpool driven publisher which aims to FORCE concurrent access,
    // so that we can confirm the test is able to catch this.
    final Publisher<Integer> concurrentAccessPublisher = new Publisher<Integer>() {

        @Override
        public void subscribe(final Subscriber<? super Integer> s) {
            s.onSubscribe(new NoopSubscription() {

                @Override
                public void request(final long n) {
                    Runnable signalling = new Runnable() {

                        @Override
                        public void run() {
                            for (long i = 0; i < n; i++) {
                                try {
                                    // shutdown cleanly in when the threadpool is shutting down
                                    if (Thread.interrupted()) {
                                        return;
                                    }
                                    s.onNext((int) i);
                                } catch (Exception ex) {
                                    // signal others to shut down
                                    signallersPool.shutdownNow();
                                    if (ex instanceof TestEnvironment.Latch.ExpectedOpenLatchException) {
                                        if (!concurrentAccessCaused.getAndSet(true)) {
                                            throw new RuntimeException("Concurrent access detected", ex);
                                        } else {
                                            // error signalled once already, stop more errors from propagating
                                            return;
                                        }
                                    } else {
                                        throw new RuntimeException(ex);
                                    }
                                }
                            }
                        }
                    };
                    // must be guarded like this in case a Subscriber triggers request() synchronously from it's onNext()
                    while (startedSignallingThreads.getAndAdd(1) < maxSignallingThreads && !signallersPool.isShutdown()) {
                        try {
                            signallersPool.execute(signalling);
                        } catch (RejectedExecutionException ex) {
                            // ignore, should be safe as it means the pool is shutting down -> which means we triggered the problem we wanted to
                            return;
                        }
                    }
                }
            });
        }
    };
    try {
        requireTestFailure(new ThrowingRunnable() {

            @Override
            public void run() throws Throwable {
                customPublisherVerification(concurrentAccessPublisher).stochastic_spec103_mustSignalOnMethodsSequentially();
            }
        }, "Illegal concurrent access detected");
    } finally {
        signallersPool.shutdownNow();
        signallersPool.awaitTermination(1, TimeUnit.SECONDS);
    }
}
Also used : Publisher(org.reactivestreams.Publisher) TestException(org.reactivestreams.tck.support.TestException) RejectedExecutionException(java.util.concurrent.RejectedExecutionException) RejectedExecutionException(java.util.concurrent.RejectedExecutionException) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) Subscriber(org.reactivestreams.Subscriber) ExecutorService(java.util.concurrent.ExecutorService) Test(org.testng.annotations.Test)

Example 25 with Subscriber

use of org.reactivestreams.Subscriber in project RxJava by ReactiveX.

the class FlowableSequenceEqualTest method doubleErrorFlowable.

@Test
public void doubleErrorFlowable() {
    List<Throwable> errors = TestHelper.trackPluginErrors();
    try {
        Flowable.sequenceEqual(Flowable.never(), new Flowable<Object>() {

            @Override
            protected void subscribeActual(Subscriber<? super Object> s) {
                s.onSubscribe(new BooleanSubscription());
                s.onError(new TestException("First"));
                s.onError(new TestException("Second"));
            }
        }, 8).toFlowable().test().assertFailureAndMessage(TestException.class, "First");
        TestHelper.assertUndeliverable(errors, 0, TestException.class, "Second");
    } finally {
        RxJavaPlugins.reset();
    }
}
Also used : BooleanSubscription(io.reactivex.internal.subscriptions.BooleanSubscription) TestSubscriber(io.reactivex.subscribers.TestSubscriber) Subscriber(org.reactivestreams.Subscriber)

Aggregations

Subscriber (org.reactivestreams.Subscriber)26 Subscription (org.reactivestreams.Subscription)16 Publisher (org.reactivestreams.Publisher)8 AtomicBoolean (java.util.concurrent.atomic.AtomicBoolean)6 AtomicInteger (java.util.concurrent.atomic.AtomicInteger)5 Test (org.junit.Test)5 ByteBuf (io.netty.buffer.ByteBuf)4 BooleanSubscription (io.reactivex.internal.subscriptions.BooleanSubscription)4 TestSubscriber (io.reactivex.subscribers.TestSubscriber)3 InetSocketAddress (java.net.InetSocketAddress)3 AtomicReference (java.util.concurrent.atomic.AtomicReference)3 Exchange (org.apache.camel.Exchange)3 Test (org.testng.annotations.Test)3 TransformablePublisher (ratpack.stream.TransformablePublisher)3 ReactiveSubscription (reactor.rx.subscription.ReactiveSubscription)3 Flowable (io.reactivex.Flowable)2 TestException (io.reactivex.exceptions.TestException)2 ExecutorService (java.util.concurrent.ExecutorService)2 RejectedExecutionException (java.util.concurrent.RejectedExecutionException)2 RouteBuilder (org.apache.camel.builder.RouteBuilder)2