Kensuke Kousaka's Blog

Notes for Developing Software, Service.

RxJavaでのExponential Backoffの実装

Exponential Backoffとは、リトライの間隔を1秒 -> 2秒 -> 4秒 -> 8秒 -> 16秒という風に増加させていくアルゴリズムである。これを用いることでクライアント及びリクエスト先サーバにおける度重なるリトライによる処理負荷を軽減できる。

RxJavaにおいてこれを実装したサンプルコードを以下に記す。

//
.retryWhen(errors -> errors
  .zipWith(Observable.range(1, MAX_RETRIES), (error, attempt) -> Pair::new)
  .flatMap(pair -> {
    // pair.firstにはExceptionが、pair.secondには現在のリトライ回数が入っている
    // pair.firstのExceptionを元に条件判定し、そのまま例外を親に吐きたいなら、以下のように実装する
    if (pair.first instanceof UnknownHostException) {
      return Observable.create(sub -> errors.tryOnError(pair.first));
    }
    
    // Exponential Backoffを実行したい場合は、以下のように実装すればいい
    return Observable.timer((long) Math.pow(pair.second - 1, 2), TimeUnit.SECONDS);
  }
)