child.add(sourceSubscriptions);
final PublishSubject<Notification<?>> terminals = PublishSubject.create();
final Action0 subscribeToSource = new Action0() {
@Override
public void call() {
Subscriber<T> terminalDelegatingSubscriber = new Subscriber<T>() {
@Override
public void onCompleted() {
unsubscribe();
terminals.onNext(Notification.createOnCompleted());
}
@Override
public void onError(Throwable e) {
unsubscribe();
terminals.onNext(Notification.createOnError(e));
}
@Override
public void onNext(T v) {
child.onNext(v);
}
};
// new subscription each time so if it unsubscribes itself it does not prevent retries
// by unsubscribing the child subscription
sourceSubscriptions.add(terminalDelegatingSubscriber);
source.unsafeSubscribe(terminalDelegatingSubscriber);
}
};
final Observable<?> restarts = f.call(
// lifting in a custom operator to kind of do a merge/map/filter thing.
terminals.lift(new Operator<Notification<?>, Notification<?>>() {
@Override
public Subscriber<? super Notification<?>> call(final Subscriber<? super Notification<?>> filteredTerminals) {
return new Subscriber<Notification<?>>(filteredTerminals) {
@Override
public void onCompleted() {
filteredTerminals.onCompleted();
}
@Override
public void onError(Throwable e) {
filteredTerminals.onError(e);
}
@Override
public void onNext(Notification<?> t) {
if (t.isOnCompleted() && stopOnComplete) child.onCompleted();
else if (t.isOnError() && stopOnError) child.onError(t.getThrowable());
else {
isLocked.set(false);
filteredTerminals.onNext(t);
}
}
};
}
}));
// subscribe to the restarts observable to know when to schedule the next redo.
child.add(inner.schedule(new Action0() {
@Override
public void call() {
restarts.unsafeSubscribe(new Subscriber<Object>(child) {
@Override
public void onCompleted() {