Search in sources :

Example 6 with SerializedSubscriber

use of io.reactivex.rxjava3.subscribers.SerializedSubscriber in project RxJava by ReactiveX.

the class SerializedSubscriberTest method runConcurrencyTest.

@Test
public void runConcurrencyTest() {
    ExecutorService tp = Executors.newFixedThreadPool(20);
    try {
        TestConcurrencySubscriber tw = new TestConcurrencySubscriber();
        // we need Synchronized + SafeSubscriber to handle synchronization plus life-cycle
        Subscriber<String> w = serializedSubscriber(new SafeSubscriber<>(tw));
        w.onSubscribe(new BooleanSubscription());
        Future<?> f1 = tp.submit(new OnNextThread(w, 12000));
        Future<?> f2 = tp.submit(new OnNextThread(w, 5000));
        Future<?> f3 = tp.submit(new OnNextThread(w, 75000));
        Future<?> f4 = tp.submit(new OnNextThread(w, 13500));
        Future<?> f5 = tp.submit(new OnNextThread(w, 22000));
        Future<?> f6 = tp.submit(new OnNextThread(w, 15000));
        Future<?> f7 = tp.submit(new OnNextThread(w, 7500));
        Future<?> f8 = tp.submit(new OnNextThread(w, 23500));
        // 12000 + 5000 + 75000 + 13500 + 22000 + 15000 + 7500 + 23500 = 173500
        Future<?> f10 = tp.submit(new CompletionThread(w, TestConcurrencySubscriberEvent.onComplete, f1, f2, f3, f4, f5, f6, f7, f8));
        try {
            Thread.sleep(1);
        } catch (InterruptedException e) {
        // ignore
        }
        waitOnThreads(f1, f2, f3, f4, f5, f6, f7, f8, f10);
        // no check of type since we don't want to test barging results here, just interleaving behavior
        int numNextEvents = tw.assertEvents(null);
        assertEquals(173500, numNextEvents);
    // System.out.println("Number of events executed: " + numNextEvents);
    } catch (Throwable e) {
        fail("Concurrency test failed: " + e.getMessage());
        e.printStackTrace();
    } finally {
        tp.shutdown();
        try {
            tp.awaitTermination(25000, TimeUnit.MILLISECONDS);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}
Also used : BooleanSubscription(io.reactivex.rxjava3.internal.subscriptions.BooleanSubscription)

Example 7 with SerializedSubscriber

use of io.reactivex.rxjava3.subscribers.SerializedSubscriber in project RxJava by ReactiveX.

the class SerializedSubscriberTest method threadStarvation.

/**
 * Demonstrates thread starvation problem.
 *
 * No solution on this for now. Trade-off in this direction as per https://github.com/ReactiveX/RxJava/issues/998#issuecomment-38959474
 * Probably need backpressure for this to work
 *
 * When using SynchronizedSubscriber we get this output:
 *
 * {@code p1: 18 p2: 68 =>} should be close to each other unless we have thread starvation
 *
 * When using SerializedSubscriber we get:
 *
 * {@code p1: 1 p2: 2445261 =>} should be close to each other unless we have thread starvation
 *
 * This demonstrates how SynchronizedSubscriber balances back and forth better, and blocks emission.
 * The real issue in this example is the async buffer-bloat, so we need backpressure.
 *
 * @throws InterruptedException if the await is interrupted
 */
@Ignore("Demonstrates thread starvation problem. Read JavaDoc")
@Test
public void threadStarvation() throws InterruptedException {
    TestSubscriber<String> ts = new TestSubscriber<>(new DefaultSubscriber<String>() {

        @Override
        public void onComplete() {
        }

        @Override
        public void onError(Throwable e) {
        }

        @Override
        public void onNext(String t) {
            // force it to take time when delivering
            try {
                Thread.sleep(1);
            } catch (InterruptedException e) {
            }
        }
    });
    final Subscriber<String> subscriber = serializedSubscriber(ts);
    AtomicInteger p1 = new AtomicInteger();
    AtomicInteger p2 = new AtomicInteger();
    subscriber.onSubscribe(new BooleanSubscription());
    ResourceSubscriber<String> as1 = new ResourceSubscriber<String>() {

        @Override
        public void onNext(String t) {
            subscriber.onNext(t);
        }

        @Override
        public void onError(Throwable t) {
            RxJavaPlugins.onError(t);
        }

        @Override
        public void onComplete() {
        }
    };
    ResourceSubscriber<String> as2 = new ResourceSubscriber<String>() {

        @Override
        public void onNext(String t) {
            subscriber.onNext(t);
        }

        @Override
        public void onError(Throwable t) {
            RxJavaPlugins.onError(t);
        }

        @Override
        public void onComplete() {
        }
    };
    infinite(p1).subscribe(as1);
    infinite(p2).subscribe(as2);
    Thread.sleep(100);
    System.out.println("p1: " + p1.get() + " p2: " + p2.get() + " => should be close to each other unless we have thread starvation");
    // fairly distributed within 10000 of each other
    assertEquals(p1.get(), p2.get(), 10000);
    as1.dispose();
    as2.dispose();
}
Also used : BooleanSubscription(io.reactivex.rxjava3.internal.subscriptions.BooleanSubscription)

Example 8 with SerializedSubscriber

use of io.reactivex.rxjava3.subscribers.SerializedSubscriber in project RxJava by ReactiveX.

the class SerializedSubscriberTest method completeReentry.

@Test
public void completeReentry() {
    final AtomicReference<Subscriber<Integer>> serial = new AtomicReference<>();
    TestSubscriber<Integer> ts = new TestSubscriber<Integer>() {

        @Override
        public void onNext(Integer v) {
            serial.get().onComplete();
            serial.get().onComplete();
            super.onNext(v);
        }
    };
    SerializedSubscriber<Integer> sobs = new SerializedSubscriber<>(ts);
    sobs.onSubscribe(new BooleanSubscription());
    serial.set(sobs);
    sobs.onNext(1);
    ts.assertValue(1);
    ts.assertComplete();
    ts.assertNoErrors();
}
Also used : BooleanSubscription(io.reactivex.rxjava3.internal.subscriptions.BooleanSubscription)

Example 9 with SerializedSubscriber

use of io.reactivex.rxjava3.subscribers.SerializedSubscriber in project RxJava by ReactiveX.

the class FlowableBufferTimed method subscribeActual.

@Override
protected void subscribeActual(Subscriber<? super U> s) {
    if (timespan == timeskip && maxSize == Integer.MAX_VALUE) {
        source.subscribe(new BufferExactUnboundedSubscriber<>(new SerializedSubscriber<>(s), bufferSupplier, timespan, unit, scheduler));
        return;
    }
    Scheduler.Worker w = scheduler.createWorker();
    if (timespan == timeskip) {
        source.subscribe(new BufferExactBoundedSubscriber<>(new SerializedSubscriber<>(s), bufferSupplier, timespan, unit, maxSize, restartTimerOnMaxSize, w));
        return;
    }
    // Can't use maxSize because what to do if a buffer is full but its
    // timespan hasn't been elapsed?
    source.subscribe(new BufferSkipBoundedSubscriber<>(new SerializedSubscriber<>(s), bufferSupplier, timespan, timeskip, unit, w));
}
Also used : SerializedSubscriber(io.reactivex.rxjava3.subscribers.SerializedSubscriber) Worker(io.reactivex.rxjava3.core.Scheduler.Worker)

Example 10 with SerializedSubscriber

use of io.reactivex.rxjava3.subscribers.SerializedSubscriber in project RxJava by ReactiveX.

the class FlowableDelay method subscribeActual.

@Override
protected void subscribeActual(Subscriber<? super T> t) {
    Subscriber<? super T> downstream;
    if (delayError) {
        downstream = t;
    } else {
        downstream = new SerializedSubscriber<>(t);
    }
    Scheduler.Worker w = scheduler.createWorker();
    source.subscribe(new DelaySubscriber<>(downstream, delay, unit, w, delayError));
}
Also used : Worker(io.reactivex.rxjava3.core.Scheduler.Worker)

Aggregations

BooleanSubscription (io.reactivex.rxjava3.internal.subscriptions.BooleanSubscription)13 TestException (io.reactivex.rxjava3.exceptions.TestException)5 Worker (io.reactivex.rxjava3.core.Scheduler.Worker)2 SerializedSubscriber (io.reactivex.rxjava3.subscribers.SerializedSubscriber)1