RX Java - повторите код, который выдает исключение
Я пытаюсь использовать RX Java, чтобы использовать некоторые данные, поступающие из источника, который продолжает отправлять объекты.
Мне интересно, как реализовать политику повторных попыток для случаев, когда мой собственный код вызывает исключение. Например, сетевое исключение должно инициировать повторную попытку с экспоненциальной политикой отката.
Некоторый код:
message.map(this::processMessage)
.subscribe((message)->{
//do something after mapping
});
processMessage(message)
это метод, который содержит рискованный код, который может дать сбой, и его часть кода, которую я хочу повторить, но я не хочу, чтобы наблюдаемое получало данные из источника.
Есть мысли по этому поводу?
3 ответа
message
.map(this::processMessage)
.retryWhen(errors -> errors.flatMap(error -> {
if (error instanceof IOException) {
return Observable.just(null);
}
// For anything else, don't retry
return Observable.error(error);
})
subscribe(
System.out::println,
error -> System.out.println("Error!")
);
или поймай ошибку
message.map(this::processMessage)
.onErrorReturn(error -> "Empty result")
.subscribe((message)->{})
или выдает ошибку
message
.map(this::processMessage)
.doOnError(throwable -> Log.e(TAG, "Throwable " + throwable.getMessage()))
.subscribe(
System.out::println,
error -> System.out.println("Error!")
);
Не проверено, но повторяется, когда отличается от повторения, когда он вызывается не только в onComplete.
http://blog.danlew.net/2016/01/25/rxjavas-repeatwhen-and-retrywhen-explained/-> Каждая ошибка отображается на карте так, что мы можем либо вернуть onNext(null) (для запуска повторной подписки) или onError(ошибка) (чтобы избежать повторной подписки).
Политика возврата:
source.retryWhen(errors ->
errors
.zipWith(Observable.range(1, 3), (n, i) -> i)
.flatMap(retryCount -> Observable.timer((long) Math.pow(5, retryCount), TimeUnit.SECONDS))
);
flatMap + timer предпочтительнее, чем задержка в этом случае, потому что это позволяет нам изменять задержку на количество повторных попыток. Вышеприведенное повторяет три раза и задерживает каждое повторение на 5 ^ retryCount, давая вам экспоненциальный откат только с несколькими операторами!
Возьмите пример из статей:
http://kevinmarlow.me/better-networking-with-rxjava-and-retrofit-on-android/
Они помогли мне в один день.
Недавно я разработал библиотеку, которая точно соответствует вашим потребностям.
Если вы объединяете Exponential
стратегия с backupObservable
вы получите ожидаемый результат.