retryWhen在前面的Observable遇到错误时会触发
static void testRetryWhen() {
OkHttpClient.Builder httpClient = new OkHttpClient.Builder();
httpClient.addInterceptor(chain -> {
Request original = chain.request();
Request.Builder requestBuilder = original.newBuilder();
Request request = requestBuilder.method(original.method(), original.body()).build();
return chain.proceed(request);
});
OkHttpClient client = httpClient.build();
Retrofit retrofit = new Retrofit.Builder().baseUrl("https://www.easy-mock.com/mock/5bf3abf638ebc65a60426891/example/").addConverterFactory
(GsonConverterFactory.create()).addCallAdapterFactory(RxJava2CallAdapterFactory
.create()).client(client).build();
Service mService = retrofit.create(Service.class);
mService.get1()
//总共重试3次,重试间隔3000毫秒
.retryWhen(new RetryWithFunction(3))
.subscribe(items -> {
System.out.println(items);
}, new Consumer() {
@Override
public void accept(Throwable throwable) throws Exception {
throwable.printStackTrace();
}
});
}
public class RetryWithFunction implements
Function, Observable>> {
private final int maxRetries;
private int retryCount;
public RetryWithFunction(int maxRetries) {
this.maxRetries = maxRetries;
}
@Override
public Observable> apply(Observable extends Throwable> attempts) throws Exception {
return attempts
.flatMap((Throwable throwable) -> {
if (++retryCount <= maxRetries) {
// When this Observable calls onNext, the original Observable will be retried (i.e. re-subscribed).
System.out.println("get error, retry count " + retryCount);
return Observable.just("" + retryCount);
}
// Max retries hit. Just pass the error along.
return Observable.error(throwable);
});
}
}
输出:
get error, retry count 1
get error, retry count 2
get error, retry count 3
error
如果看一下retryWhen里面的具体实现:
public final Observable retryWhen(
final Function super Observable, ? extends ObservableSource>> handler) {
ObjectHelper.requireNonNull(handler, "handler is null");
return RxJavaPlugins.onAssembly(new ObservableRetryWhen(this, handler));
}
这里主要返回了一个ObservableRetryWhen,然后当后面调用subscribe的时候,这里会调用到ObservableRetryWhen的subscribeActual
@Override
protected void subscribeActual(Observer super T> observer) {
Subject signaller = PublishSubject.create().toSerialized();
ObservableSource> other;
try {
other = ObjectHelper.requireNonNull(handler.apply(signaller), "The handler returned a null ObservableSource");
} catch (Throwable ex) {
Exceptions.throwIfFatal(ex);
EmptyDisposable.error(ex, observer);
return;
}
RepeatWhenObserver parent = new RepeatWhenObserver(observer, signaller, source);
observer.onSubscribe(parent);
other.subscribe(parent.inner);
parent.subscribeNext();
}
这里主要步骤如下:
1、创建一个SerializedSubject它的actual是PublishSubject
2、把前面创建的SerializedSubject作为参数调用retryWhen的hander(这里我们返回了一个ObservableFlatMap)
3、新建一个RepeatWhenObserver把前面我们的observer(观察者),第一步创建的SerializedSubject以及我们原始的source(BodyObservable)作为参数传给进去
4、调用observer的onSubscribe说明开始订阅
5、调用第2步返回的ObservableFlatMap订阅RepeatWhenObserver的inner(InnerRepeatObserver)
6、调用RepeatWhenObserver的subscribeNext方法
我们主要看5 和 6.
先看5:
最终会调用到SerializedSubject的subscribeActual(第二步传递的参数是是第一步创建的SerializedSubject),SerializedSubject的subscribeActual最终调用PublishSubject的subscribeActual
protected void subscribeActual(Observer super T> t) {
PublishDisposable ps = new PublishDisposable(t, this);
t.onSubscribe(ps);
if (add(ps)) {
// if cancellation happened while a successful add, the remove() didn't work
// so we need to do it again
if (ps.isDisposed()) {
remove(ps);
}
} else {
Throwable ex = error;
if (ex != null) {
t.onError(ex);
} else {
t.onComplete();
}
}
}
这里创建了一个PublishDisposable,把自己和前面在ObservableFlatMap创建的MergeObserver传进去
调用add方法把PublishDisposable添加到subscribers
第5步就完了,然后我们看看前面的第6步subscribeNext
void subscribeNext() {
if (wip.getAndIncrement() == 0) {
do {
if (isDisposed()) {
return;
}
if (!active) {
active = true;
source.subscribe(this);
}
} while (wip.decrementAndGet() != 0);
}
}
这里先获取值为0则进去,然后进行加1操作,这里第一次来,wip为0
然后里面调用 source.subscribe(this);这里的source是前面的BodyObservable
这里最终会调用到CallExecuteObservable的subscribeActual
@Override protected void subscribeActual(Observer super Response> observer) {
// Since Call is a one-shot type, clone it for each new observer.
Call call = originalCall.clone();
observer.onSubscribe(new CallDisposable(call));
boolean terminated = false;
try {
Response response = call.execute();
if (!call.isCanceled()) {
observer.onNext(response);
}
if (!call.isCanceled()) {
terminated = true;
observer.onComplete();
}
} catch (Throwable t) {
Exceptions.throwIfFatal(t);
if (terminated) {
RxJavaPlugins.onError(t);
} else if (!call.isCanceled()) {
try {
observer.onError(t);
} catch (Throwable inner) {
Exceptions.throwIfFatal(inner);
RxJavaPlugins.onError(new CompositeException(t, inner));
}
}
}
}
这里会发起网络请求,然后调用 observer.onNext(response);这里的observer是BodyObserver
@Override public void onNext(Response response) {
if (response.isSuccessful()) {
observer.onNext(response.body());
} else {
terminated = true;
Throwable t = new HttpException(response);
try {
observer.onError(t);
} catch (Throwable inner) {
Exceptions.throwIfFatal(inner);
RxJavaPlugins.onError(new CompositeException(t, inner));
}
}
}
这里我们假设网络异常,会new一个HttpException然后调用onError,这里BodyObserver中的observer是0RepeatWhenObserver
@Override
public void onError(Throwable e) {
active = false;
signaller.onNext(e);
}
这里signaller是我们传进来的SerializedSubject,最终会调用PublishSubject的onNext
@Override
public void onNext(T t) {
ObjectHelper.requireNonNull(t, "onNext called with null. Null values are generally not allowed in 2.x operators and sources.");
for (PublishDisposable pd : subscribers.get()) {
pd.onNext(t);
}
}
这里subscribers我们前面添加了一个,调用PublishDisposable的onNext最终又调用到ObservableFlatMap中MergeObserver的noNext
@Override
public void onNext(T t) {
// safeguard against misbehaving sources
if (done) {
return;
}
ObservableSource extends U> p;
try {
p = ObjectHelper.requireNonNull(mapper.apply(t), "The mapper returned a null ObservableSource");
} catch (Throwable e) {
Exceptions.throwIfFatal(e);
upstream.dispose();
onError(e);
return;
}
if (maxConcurrency != Integer.MAX_VALUE) {
synchronized (this) {
if (wip == maxConcurrency) {
sources.offer(p);
return;
}
wip++;
}
}
subscribeInner(p);
}
这里主要是调用flatMap的变换函数,在变换函数中我们实现自己的逻辑,并对最终的结果调用subscribeInner进行重新订阅
void subscribeInner(ObservableSource extends U> p) {
for (;;) {
if (p instanceof Callable) {
if (tryEmitScalar(((Callable extends U>)p)) && maxConcurrency != Integer.MAX_VALUE) {
boolean empty = false;
synchronized (this) {
p = sources.poll();
if (p == null) {
wip--;
empty = true;
}
}
if (empty) {
drain();
break;
}
} else {
break;
}
} else {
InnerObserver inner = new InnerObserver(this, uniqueId++);
if (addInner(inner)) {
p.subscribe(inner);
}
break;
}
}
}
当没超过次数时,我们是调用Observable.just返回的一个ObservableJust他是Callable的实例,所以走上面if
最终调用tryEmitScalar 会调用到RepeatWhenObserver的subscribeNext
void subscribeNext() {
if (wip.getAndIncrement() == 0) {
do {
if (isDisposed()) {
return;
}
if (!active) {
active = true;
source.subscribe(this);
}
} while (wip.decrementAndGet() != 0);
}
}
这次进来的时候wip为1,不为0不会进去,wip加1变成了2.然后回到第一次调用subscribeNext的时候,由于刚进行了加1操作,这次先进行减1操作,然后值为1,不为0,继续执行上面的循环。
当我们在retryWhen的Function中调用Observable.error的时候,我们看看
void subscribeInner(ObservableSource extends U> p) {
for (;;) {
if (p instanceof Callable) {
if (tryEmitScalar(((Callable extends U>)p)) && maxConcurrency != Integer.MAX_VALUE) {
boolean empty = false;
synchronized (this) {
p = sources.poll();
if (p == null) {
wip--;
empty = true;
}
}
if (empty) {
drain();
break;
}
} else {
break;
}
} else {
InnerObserver inner = new InnerObserver(this, uniqueId++);
if (addInner(inner)) {
p.subscribe(inner);
}
break;
}
}
}
在这里ObservableError不是Callable实例,所以走下面
最终调用ObservableError的subscribeActual
@Override
public void subscribeActual(Observer super T> observer) {
Throwable error;
try {
error = ObjectHelper.requireNonNull(errorSupplier.call(), "Callable returned null throwable. Null values are generally not allowed in 2.x operators and sources.");
} catch (Throwable t) {
Exceptions.throwIfFatal(t);
error = t;
}
EmptyDisposable.error(error, observer);
}
最终调用到我们的onError
这里如果我们把RetryWithFunction改为如下
public class RetryWithFunction implements
Function, Observable>> {
private final int maxRetries;
private int retryCount;
public RetryWithFunction(int maxRetries) {
this.maxRetries = maxRetries;
}
@Override
public Observable> apply(Observable extends Throwable> attempts) throws Exception {
return attempts.map(new Function() {
@Override
public Observable apply(Throwable o) throws Exception {
if (++retryCount <= maxRetries) {
// // When this Observable calls onNext, the original Observable will be retried (i.e. re-subscribed).
System.out.println("get error, , retry count " + retryCount);
return Observable.just("" + retryCount);
}
System.out.println("Observable.error ----");
return Observable.error(o);
}
});
}
}
把flatMap改为map之后
执行的结果是
get error, , retry count 1
get error, , retry count 2
get error, , retry count 3
Observable.error ----
Observable.error ----
Observable.error ----
Observable.error ----
Observable.error ----
Observable.error ----
Observable.error ----
Observable.error ----
Observable.error ----
Observable.error ----
Observable.error ----
一直打Observable.error ----说明一直在retry
这里原因是跟他的MapObserver有关
@Override
public void onNext(T t) {
if (done) {
return;
}
if (sourceMode != NONE) {
downstream.onNext(null);
return;
}
U v;
try {
v = ObjectHelper.requireNonNull(mapper.apply(t), "The mapper function returned a null value.");
} catch (Throwable ex) {
fail(ex);
return;
}
downstream.onNext(v);
}
这里调用的是InnerRepeatObserver的onNext
public void onNext(Object t) {
innerNext();
}
所以不管map返回的是什么值,都会一直调用到subscribeNext进行加一操作然后一直循环
如果把RetryWithFunction改成如下
public class RetryWithFunction implements
Function, Observable>> {
private final int maxRetries;
private int retryCount;
public RetryWithFunction(int maxRetries) {
this.maxRetries = maxRetries;
}
@Override
public Observable> apply(Observable extends Throwable> attempts) throws Exception {
return attempts;
}
}
这个也会像上面一样,一直调用subscribeNext执行。