RxJava Single<>有计数,谓词和延迟

时间:2018-01-26 09:29:29

标签: java rx-java rx-java2

我正在进行改造网络呼叫,它们都使用Single<>退货。在任何错误上,我基于谓词进行重试,最多3次。但我想引入一个延迟或指数退避。如何添加此延迟?

public <T> SingleTransformer<T, T> applySchIoAndRetry() {

    return new SingleTransformer<T, T>() {
        @Override
        public SingleSource<T> apply(Single<T> upstream) {
            return upstream
                    .subscribeOn(Schedulers.io())
                    .retry(3, new Predicate<Throwable>() {
                        @Override
                        public boolean test(Throwable throwable) throws Exception {

                            if (throwable instanceof HttpException) {
                                HttpException exception = (HttpException) throwable;
                                return (exception.code() != 400);
                            }

                            return false;
                        }
                    });
        }
    };
}

我在这里称呼它:

public Single<Foo> bar() {
    return apiService.foobar()
            .compose(rxHelper.applySchIoAndRetry());
}

1 个答案:

答案 0 :(得分:0)

非常感谢@akarnokd指向重试时Javadoc。基于此,这是我正在使用的解决方案:

public <T> SingleTransformer<T, T> applySchIoAndRetry() {

    return new SingleTransformer<T, T>() {
        @Override
        public SingleSource<T> apply(Single<T> upstream) {
            return upstream
                    .subscribeOn(Schedulers.io())
                    .retryWhen(errors -> {
                        AtomicInteger counter = new AtomicInteger();
                        return errors
                                .takeWhile(throwable -> {

                                    if (counter.getAndIncrement() != 3) {

                                        if (throwable instanceof HttpException) {
                                            HttpException exception = (HttpException) throwable;
                                            return (exception.code() == 400);
                                        }
                                    }

                                    return false;
                                })
                                .flatMap(e -> {
                                    System.out.println("delay retry by " + counter.get() + " second(s)");
                                    return Flowable.timer(counter.get(), TimeUnit.SECONDS);
                                });
                    });
        }
    };
}