Subscriber's onCompleted is not called when return Observable.empty() in retryWhen()
See original GitHub issueI was testing out RxJava’s retryWhen()
function an this problem occurred.
retryWhen()
's docs says:
Returns an Observable that emits the same values as the source observable with the exception of an onError. An onError notification from the source will result in the emission of a Throwable item to the Observable provided as an argument to the notificationHandler function. If that Observable calls onComplete or onError then retry will call onCompleted or onError on the child subscription. Otherwise, this Observable will resubscribe to the source Observable.
When I returns Observable.empty()
in flatMap()
, the subscriber’s onCompleted never gets called despite Observable.empty()
's docs says:
Returns an Observable that emits no items to the Observer and immediately invokes its onCompleted method.
If I replace Observable.empty()
with Observable.error(new Exception("New Exception!"))
, the new exception is thrown to the subscriber’s onError(). It’s correct according to the retryWhen()
's docs.
Following is my code:
Observable.create(new Observable.OnSubscribe<Integer>() {
@Override
public void call(Subscriber<? super Integer> subscriber) {
subscriber.onNext(10);
sleep(1000);
subscriber.onNext(20);
sleep(1000);
subscriber.onError(new Exception("My Exception!"));
}
}).retryWhen(new Func1<Observable<? extends Throwable>, Observable<?>>() {
@Override
public Observable<?> call(Observable<? extends Throwable> observable) {
return observable.flatMap(new Func1<Throwable, Observable<?>>() {
@Override
public Observable<?> call(Throwable throwable) {
log("throwable = " + throwable.getMessage());
return Observable.empty();
// return Observable.error(new Exception("New Exception!"));
}
});
}
}).subscribeOn(Schedulers.newThread()).subscribe(new Subscriber<Object>() {
@Override
public void onCompleted() {
log("onCompleted");
}
@Override
public void onError(Throwable e) {
log("onError: " + e.getMessage());
}
@Override
public void onNext(Object integer) {
log("onNext: " + integer);
}
});
private void sleep(long duration) {
try {
Thread.sleep(duration);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
private void log(String s) {
Log.e("linhln", s);
}
Issue Analytics
- State:
- Created 8 years ago
- Reactions:1
- Comments:11 (3 by maintainers)
Hi @akarnokd, I’m quite new to Reactive so I don’t get your trick.
So to make it simpler, I have this piece of code. The problem is
onCompleted
is not called despiteObservable.empty()
, could you please show me how to apply the trick to makeonCompleted
gets called.Oh I see. Because the observable passed in as the argument could still emit a new Throwable (that may result in a flatMap of more emissions). Yes this makes more sense. You would have to complete the outer observable in order to ensure that no further inner observables can be merged.
@akarnokd @abersnaze If we begin to create observables that have limited operator sets then it would be good to pass in an observable that did not have flatMap to the notification handler (in 2.x of course).