-
Notifications
You must be signed in to change notification settings - Fork 7.6k
Description
I have experienced some unexpected behaviors of publish() and connect() in my project.
Hopefully it's not my misunderstanding since I'm a newbie to Rx.
I will use an Observer that simply print onNext, onError, onCompleted.
public static class PrintObserver<T> implements Observer<T> {
@Override
public void onCompleted() {
System.out.println("onCompleted");
}
@Override
public void onError(Throwable e) {
System.out.println("onError: " + e);
}
@Override
public void onNext(T t) {
System.out.println("onNext: " + t);
}
}The simplified scenarios are as follows:
- ConnectableObservable stops emitting without unsubscribing from source.
Observable<Integer> source = Observable.range(0, 1000);
ConnectableObservable<Integer> pub1 = source.publish();
ConnectableObservable<Integer> pub2 = pub1.publish();
pub2.connect();
//pub2.subscribe();
pub1.subscribe(new PrintObserver<Integer>());
pub1.connect();I expected the output to be 'onNext: 0' up to 'onNext: 999', then 'onCompleted', but it stops at onNext: 127 in my test.
But if I uncomment //pub2.subscribe();, namely have something subscribe to pub2, it will work as expected. Or else if I do not pub2.connect(), it will also work.
The code may looks silly, but it may not if I put some operator which does expensive computations before publishing as pub2. BTW, what I want is to do some intermediate computations only once if pub2 is subscribed by many subscribers or piped to different downstream operators. If there're better ways to do that, please kindly let me know.
publish()behaves likereplay()
try {
Observable<Long> source = Observable.interval(1, TimeUnit.SECONDS).take(10);
ConnectableObservable<Long> pub = source.publish();
pub.connect();
Thread.sleep(2500);
pub.subscribe(new PrintObserver<Long>());
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}I expected that after pub.connect(), source will start emitting, and when pub is subscribed after 2.5 sec, 'onNext: 0' and 'onNext: 1' will be missed by this subscriber. However, I got them all together at 2.5 sec, and from 3rd second, I got the following onNext: 2 and so on. This looks like a replay() behavior to me.