Rxjava retryWhen操作符

 

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 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, ? 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 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 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> 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 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 p) {
            for (;;) {
                if (p instanceof Callable) {
                    if (tryEmitScalar(((Callable)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 p) {
            for (;;) {
                if (p instanceof Callable) {
                    if (tryEmitScalar(((Callable)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 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 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 attempts) throws Exception {
        return attempts;
    }
}

这个也会像上面一样,一直调用subscribeNext执行。

你可能感兴趣的:(RxJava)