@Override public Publisher<Integer> createPublisher(long elements) { return Flowable.range(0, (int)elements).replay().autoConnect() ; } }
/** * Connects to the upstream {@code ConnectableFlowable} if the number of subscribed * subscriber reaches 1 and disconnect after the specified * timeout if all subscribers have unsubscribed. * <dl> * <dt><b>Backpressure:</b></dt> * <dd>The operator itself doesn't interfere with backpressure which is determined by the upstream * {@code ConnectableFlowable}'s backpressure behavior.</dd> * <dt><b>Scheduler:</b></dt> * <dd>This {@code refCount} overload operates on the specified {@link Scheduler}.</dd> * </dl> * <p>History: 2.1.14 - experimental * @param timeout the time to wait before disconnecting after all subscribers unsubscribed * @param unit the time unit of the timeout * @param scheduler the target scheduler to wait on before disconnecting * @return the new Flowable instance * @since 2.2 */ @CheckReturnValue @SchedulerSupport(SchedulerSupport.CUSTOM) @BackpressureSupport(BackpressureKind.PASS_THROUGH) public final Flowable<T> refCount(long timeout, TimeUnit unit, Scheduler scheduler) { return refCount(1, timeout, unit, scheduler); }
@Override public void connect(Consumer<? super Disposable> connection) { cf.connect(connection); }
@Test public void syncFusedObserveOn2() { ConnectableFlowable<Integer> cf = Flowable.range(0, 1000).publish(); Flowable<Integer> obs = cf.observeOn(ImmediateThinScheduler.INSTANCE); for (int i = 0; i < 1000; i++) { for (int j = 1; j < 6; j++) { List<TestSubscriber<Integer>> tss = new ArrayList<TestSubscriber<Integer>>(); for (int k = 1; k < j; k++) { TestSubscriber<Integer> ts = new TestSubscriber<Integer>(); tss.add(ts); obs.subscribe(ts); } Disposable connection = cf.connect(); for (TestSubscriber<Integer> ts : tss) { ts.awaitDone(5, TimeUnit.SECONDS) .assertSubscribed() .assertValueCount(1000) .assertNoErrors() .assertComplete(); } connection.dispose(); } } }
@Override public void run() { cf.subscribe(ts1); } };
@Test public void connectConsumerThrows() { ConnectableFlowable<Integer> cf = Flowable.range(1, 2) .replay(); try { cf.connect(new Consumer<Disposable>() { @Override public void accept(Disposable t) throws Exception { throw new TestException(); } }); fail("Should have thrown"); } catch (TestException ex) { // expected } cf.test().assertEmpty().cancel(); cf.connect(); cf.test().assertResult(1, 2); }
@Test public void testTakeUntilWithPublishedStream() { Flowable<Integer> xs = Flowable.range(0, Flowable.bufferSize() * 2); TestSubscriber<Integer> ts = new TestSubscriber<Integer>(); ConnectableFlowable<Integer> xsp = xs.publish(); xsp.takeUntil(xsp.skipWhile(new Predicate<Integer>() { @Override public boolean test(Integer i) { return i <= 3; } })).subscribe(ts); xsp.connect(); System.out.println(ts.values()); }
@Test(timeout = 5000) public void schedulerTestRx() throws InterruptedException { CountDownLatch latch = new CountDownLatch(2); ConnectableFlowable<Integer> connectableFlux = Flowable.just(1, 2, 3, 4, 5).publish(); connectableFlux .doOnEach(System.out::println) .subscribe(v -> {} , e -> {}, latch::countDown); connectableFlux .observeOn(Schedulers.computation()) .doOnEach(System.out::println) .map(v -> v * 10) .observeOn(Schedulers.single()) .doOnEach(System.out::println) .subscribeOn(Schedulers.io()) .subscribe(v -> {} , e -> {}, latch::countDown); Thread.sleep(100); connectableFlux.connect(); latch.await(); } }
@Test public void cancelOnArrival2() { ConnectableFlowable<Integer> cf = PublishProcessor.<Integer>create() .replay(Integer.MAX_VALUE); cf.test(); cf .autoConnect() .test(Long.MAX_VALUE, true) .assertEmpty(); }
/** * Child Subscribers will observe the events of the ConnectableObservable on the * specified scheduler. * @param <T> the value type * @param cf the ConnectableFlowable to wrap * @param scheduler the target scheduler * @return the new ConnectableObservable instance */ public static <T> ConnectableFlowable<T> observeOn(final ConnectableFlowable<T> cf, final Scheduler scheduler) { final Flowable<T> flowable = cf.observeOn(scheduler); return RxJavaPlugins.onAssembly(new ConnectableFlowableReplay<T>(cf, flowable)); }
@Override public void run() { cf.connect(); } };
@Test public void syncFusedObserveOn() { ConnectableFlowable<Integer> cf = Flowable.range(0, 1000).publish(); Flowable<Integer> obs = cf.observeOn(Schedulers.computation()); for (int i = 0; i < 1000; i++) { for (int j = 1; j < 6; j++) { List<TestSubscriber<Integer>> tss = new ArrayList<TestSubscriber<Integer>>(); for (int k = 1; k < j; k++) { TestSubscriber<Integer> ts = new TestSubscriber<Integer>(); tss.add(ts); obs.subscribe(ts); } Disposable connection = cf.connect(); for (TestSubscriber<Integer> ts : tss) { ts.awaitDone(5, TimeUnit.SECONDS) .assertSubscribed() .assertValueCount(1000) .assertNoErrors() .assertComplete(); } connection.dispose(); } } }
@Override public void run() { cf.subscribe(ts2); } };
@Test public void pollThrowsNoSubscribers() { ConnectableFlowable<Integer> cf = Flowable.just(1, 2) .map(new Function<Integer, Integer>() { @Override public Integer apply(Integer v) throws Exception { if (v == 2) { throw new TestException(); } return v; } }) .compose(TestHelper.<Integer>flowableStripBoundary()) .publish(); TestSubscriber<Integer> ts = cf.take(1) .test(); cf.connect(); ts.assertResult(1); }
/** * Child Subscribers will observe the events of the ConnectableObservable on the * specified scheduler. * @param <T> the value type * @param cf the ConnectableFlowable to wrap * @param scheduler the target scheduler * @return the new ConnectableObservable instance */ public static <T> ConnectableFlowable<T> observeOn(final ConnectableFlowable<T> cf, final Scheduler scheduler) { final Flowable<T> observable = cf.observeOn(scheduler); return RxJavaPlugins.onAssembly(new ConnectableFlowableReplay<T>(cf, observable)); }
@Override public void run() { cf.connect(); } };
@Test public void testObserveOn() { ConnectableFlowable<Integer> cf = Flowable.range(0, 1000).hide().publish(); Flowable<Integer> obs = cf.observeOn(Schedulers.computation()); for (int i = 0; i < 1000; i++) { for (int j = 1; j < 6; j++) { List<TestSubscriber<Integer>> tss = new ArrayList<TestSubscriber<Integer>>(); for (int k = 1; k < j; k++) { TestSubscriber<Integer> ts = new TestSubscriber<Integer>(); tss.add(ts); obs.subscribe(ts); } Disposable connection = cf.connect(); for (TestSubscriber<Integer> ts : tss) { ts.awaitDone(5, TimeUnit.SECONDS) .assertSubscribed() .assertValueCount(1000) .assertNoErrors() .assertComplete(); } connection.dispose(); } } }