RetryWhen реализации на основе значения локальной области или zip - PullRequest
0 голосов
/ 13 января 2020

Учитывая случай использования, в котором мы хотим повторить Rx Java 2, наблюдаемый с настраиваемой задержкой, которая зависит от числа повторов, наиболее часто встречающаяся реализация имеет вид:

        .retryWhen { errors ->
            Flowables.zip(errors,
                          Flowable.range(1, Int.MAX_VALUE - 1),
                          { t, retryNo -> calculateDelay(t, retryNo) })
                .flatMap { Flowable.timer(it, TimeUnit.MILLISECONDS) }
        }

По сути, архивирование с диапазоном для получения числа повторов.

Однако гораздо более простую и эффективную реализацию можно выполнить с локальным значением (давайте сделаем его атомом c, чтобы убедиться, что не сталкиваемся с потоком syn c вопросов):

        .retryWhen {
            val retryNo = AtomicInteger(0)
            errors.flatMap {
                Flowable.timer(calculateDelay(it, retryNo.incrementAndGet()), TimeUnit.MILLISECONDS)
            }
        }

В этой реализации мы:

  1. избегаем дорогого оператора zip;
  2. избегать генерации range текущего;
  3. избегать предварительной генерации и буферизации 128 значений внутри range flowable;

Есть ли какие-либо предостережения, которые я полностью пропускаю во второй реализации?

...