我想为网络呼叫创建一种指数退避。
但是,与通常的退避间隔不同,我的网络呼叫应该重复几次(延迟增加),然后完成—不管网络呼叫的结果如何。
例如,默认情况应如下所示:
→ wait 1s → network call → onNext(result)
→ wait 3s → network call → onNext(result)
→ wait 10s → network call → onNext(result)
→ onCompleted
当某些网络调用有错误时,应该记录这些错误,但不能中止任务本身。假设第二个网络调用有错误,则应该如下所示:
→ wait 1s → network call → onNext(result)
→ wait 3s → network call error → log error
→ wait 10s → network call → onNext(result)
→ onCompleted
当所有呼叫都有错误时:
→ wait 1s → network call error → log error
→ wait 3s → network call error → log error
→ wait 10s → network call error → log error
→ onCompleted
我已经有了一个可以调用网络的可观测数据,其中的代码如下所示:
public Observable<Stuff> loadStuff() {
Request request = new Request.Builder()
.url("http://example.com/stuff").build();
return myCall(request, Stuff.class);
}
public <T> Observable<T> myCall(Request request, Class<T> resultClass) {
// calls OkHttp3 and parses the result
return okhttp(request)
.flatMap(parseResponse(resultClass));
}
如何重复使用
loadStuff()
中的可观测值来实现所需的退避间隔? 最佳答案
似乎您可以使用retrywhen和onerrorreseumonext来避免管道中断,在retrywhen中,您可以返回具有指数延迟的可观测数据以实现您想要的结果。
@Test
public void observableOnErrorResumeNext() {
Subscription subscription = Observable.just(null)
.map(Object::toString)
.doOnError(failure -> System.out.println("Error:" + failure.getCause()))
.retryWhen(errors -> errors.doOnNext(o -> count++)
.flatMap(t -> count > 3 ? Observable.error(t) : Observable.just(null)),
Schedulers.newThread())
.onErrorResumeNext(t -> {
System.out.println("Error after all retries:" + t.getCause());
return Observable.just("I save the world for extinction!");
})
.subscribe(s -> System.out.println(s));
new TestSubscriber((Observer) subscription).awaitTerminalEvent(500, TimeUnit.MILLISECONDS);
}
如果需要更多示例,请在此处查看:https://github.com/politrons/reactive