3

ネットワーク呼び出しに対して一種の指数バックオフを作成したいと考えています。ただし、通常のバックオフ間隔の代わりに、ネットワーク呼び出しの結果に関係なく、ネットワーク呼び出しを数回 (遅延を増やしながら) 繰り返してから完了する必要があります。

たとえば、デフォルトのケースは次のようになります。

    → wait 1s → network call → onNext(result)
    → wait 3s → network call → onNext(result)
    → wait 10s → network call → onNext(result)
    → onCompleted

一部のネットワーク呼び出しでエラーが発生した場合、これらのエラーはログに記録されますが、タスク自体は中止されません。2 番目のネットワーク呼び出しにエラーがあるとします。その場合、次のようになります。

    → 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

コードが次のようなネットワークを呼び出すことができる Observable が既にあります。

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()Observable を繰り返し使用して目的のバックオフ間隔を達成するにはどうすればよいですか?

4

1 に答える 1

0

RetryWhenonErrorResumeNextを使用してパイプラインの中断を回避できるようです。RetryWhen では、指数関数的な遅延で Observable を返して、目的を達成できます。

      @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

于 2016-07-06T15:30:45.097 に答える