rxjava: Can I use retry() but with delay?

后端 未结 14 2301
别那么骄傲
别那么骄傲 2020-11-28 18:25

I am using rxjava in my Android app to handle network requests asynchronously. Now I would like to retry a failed network request only after a certain time has passed.

14条回答
  •  生来不讨喜
    2020-11-28 18:57

    (Kotlin) I little bit improved code with exponential backoff and applied defense emitting of Observable.range():

        fun testOnRetryWithDelayExponentialBackoff() {
        val interval = 1
        val maxCount = 3
        val ai = AtomicInteger(1);
        val source = Observable.create { emitter ->
            val attempt = ai.getAndIncrement()
            println("Subscribe ${attempt}")
            if (attempt >= maxCount) {
                emitter.onNext(Unit)
                emitter.onComplete()
            }
            emitter.onError(RuntimeException("Test $attempt"))
        }
    
        // Below implementation of "retryWhen" function, remove all "println()" for real code.
        val sourceWithRetry: Observable = source.retryWhen { throwableRx ->
            throwableRx.doOnNext({ println("Error: $it") })
                    .zipWith(Observable.range(1, maxCount)
                            .concatMap { Observable.just(it).delay(0, TimeUnit.MILLISECONDS) },
                            BiFunction { t1: Throwable, t2: Int -> t1 to t2 }
                    )
                    .flatMap { pair ->
                        if (pair.second >= maxCount) {
                            Observable.error(pair.first)
                        } else {
                            val delay = interval * 2F.pow(pair.second)
                            println("retry delay: $delay")
                            Observable.timer(delay.toLong(), TimeUnit.SECONDS)
                        }
                    }
        }
    
        //Code to print the result in terminal.
        sourceWithRetry
                .doOnComplete { println("Complete") }
                .doOnError({ println("Final Error: $it") })
                .blockingForEach { println("$it") }
    }
    

提交回复
热议问题