Hello
I am not sure this is an issue, I would rather say this is a question.
I have noticed a different behavior between RxJava 1.x and RxJava 2.x
When an observable is completed, with RxJava 1.x subscriptions get unsubscribed:
BehaviorSubject<Object> subject = BehaviorSubject.create();
Subscription subscription = subject.subscribe();
subject.onCompleted();
System.out.println(subscription.isUnsubscribed()); // display true
However with RxJava2, the subscription is not disposed when the observable is completed:
Disposable subscription = null;
@Test
public void test() {
BehaviorSubject subject = BehaviorSubject.create();
Observer<? super String> observer = new Observer<String>() {
public void onSubscribe(Disposable d) {
subscription = d;
}
...
};
subject.subscribe(observer);
subject.onComplete();
System.out.println(subscription.isDisposed()); // display false
}
Is it a wanted behavior? If so is this behavior documented somewhere?
Thanks a lot for your help
Generally, if you don't dispose a disposable received via onSubscribe it may or may not report itself as disposed. The lambda version of the subscribe() does report itself disposed when it calls the lambda for a terminal event.
In practice, there shouldn't be any reason to call isDisposed outside an operator or create method because it assumes synchronous termination, or worse, it is the reactive version of Future.get().
In the reactive world, you react to termination via the appropriate onXXX method, compose in the continuation or simply side-effect via doFinally.
Sidenote: One of the smaller but ever growing regret of mine is that I let isDisposed into the API, because I knew that will eventually trigger a bunch of inconsistency bug reports and correcting them adds more overhead. I'm glad the Reactive-Streams specification opted for no isCancelled method.
Thanks a lot for your "reactivity" and your explanations!
I agree that isCancelled is less misleading.
I have the feeling that I am not the only being confused: http://stackoverflow.com/questions/41826478/do-i-have-to-unsubscribe-from-completed-observable
Related question: Observable.doOnDispose() Javadoc mentions the following:
"Note that terminal events trigger the action unless the {@code ObservableSource} is subscribed to via {@code unsafeSubscribe()}."
Is this still true or should .doFinally()/.doOnTerminate() be the preferred option?
That's no longer true. The preferred operator is doFinally as it covers onError, onComplete and dispose as well.
Would you like to post a PR that removes that note? If so, please check the other base types for the equivalent operator as there might be copy-pasted all over the place.
Okay, thanks for clarifying. I can update the JavaDoc note later today.
Most helpful comment
Generally, if you don't dispose a disposable received via
onSubscribeit may or may not report itself as disposed. The lambda version of thesubscribe()does report itself disposed when it calls the lambda for a terminal event.In practice, there shouldn't be any reason to call
isDisposedoutside an operator orcreatemethod because it assumes synchronous termination, or worse, it is the reactive version ofFuture.get().In the reactive world, you react to termination via the appropriate onXXX method, compose in the continuation or simply side-effect via
doFinally.Sidenote: One of the smaller but ever growing regret of mine is that I let
isDisposedinto the API, because I knew that will eventually trigger a bunch of inconsistency bug reports and correcting them adds more overhead. I'm glad the Reactive-Streams specification opted for noisCancelledmethod.