Rxswift: Best way to retry with delay and max attempt count

Created on 19 May 2016  路  3Comments  路  Source: ReactiveX/RxSwift

I want to retry sequence with delay time interval and given max times, I only found out the way create delay retry, how can I add max attempt count? Here is my code.

extension ObservableType {
  public func retryWithDelay(timeInterval: Int)
    -> Observable<E> {
      return retryWhen { (attempts: Observable<ErrorType>) -> Observable<Int> in
        return Observable
          .zip(attempts, Observable.just(timeInterval), resultSelector: { (o1, o2) in
            return o2
          })
          .flatMap { i -> Observable<Int> in
            return Observable.timer(RxTimeInterval(i), period: 1, scheduler: MainScheduler.instance)
        }
      }
  }
}

Most helpful comment

Hi @retsohuang ,

I think this is how you would do this.

let maxAttempts = 4

            xs.retryWhen { (errors: Observable<ErrorType>) in
                return errors.flatMapWithIndex { (e, a) -> Observable<Int64> in
                    if a >= maxAttempts - 1 {
                        return Observable.error(e)
                    }

                    return Observable<Int64>.timer(RxTimeInterval((a + 1) * 50), scheduler: scheduler)
                }
            }

All 3 comments

Hi @retsohuang ,

I think this is how you would do this.

let maxAttempts = 4

            xs.retryWhen { (errors: Observable<ErrorType>) in
                return errors.flatMapWithIndex { (e, a) -> Observable<Int64> in
                    if a >= maxAttempts - 1 {
                        return Observable.error(e)
                    }

                    return Observable<Int64>.timer(RxTimeInterval((a + 1) * 50), scheduler: scheduler)
                }
            }

@kzaher not really solve it..

its not recommended to take data out of the stream

Here you go...

Just create a PrimitiveSequence extension that wraps around retry().
(Swift5.1 RxSwift 4.3.1)

extension PrimitiveSequence {
  func retry(maxAttempts: Int, delay: TimeInterval) -> PrimitiveSequence<Trait, Element> {
    return self.retryWhen { errors in
      return errors.enumerated().flatMap { (index, error) -> Observable<Int64> in
        if index <= maxAttempts {
          return Observable<Int64>.timer(RxTimeInterval(delay), scheduler: MainScheduler.instance)
        } else {
          return Observable.error(error)
        }
      }
    }
  }
}

Usage example: (retry 3 times, with 2 sec delay each)

yourRxStream.retry(maxAttempts: 3, delay: 2)
Was this page helpful?
0 / 5 - 0 ratings

Related issues

kzaher picture kzaher  路  3Comments

delebedev picture delebedev  路  3Comments

gaudecker picture gaudecker  路  3Comments

apoloa picture apoloa  路  3Comments

RafaelPlantard picture RafaelPlantard  路  3Comments