7
10

More than 5 years have passed since last update.

Java でリトライハンドラを実装する

Posted at

概要

Ruby の retry-handler が激しく便利そうなので Java で実装してみた」を読んで、そういう便利なものがあると知りました。せっかくなので、私も勉強を兼ねて見よう見まねで実装してみました。

リトライハンドラの機能

例外が発生しうる処理をx回試行します。例外が発生しなければ1回で終了し、発生した場合は最大指定回数繰り返します。
HTTP アクセス等の、例外が発生しても成功するまで何回か繰り返してほしい処理で役に立ちます。


実装

GitHub repository

Command を受け取るだけの interface を定義しておきます。

Action
public interface Action {
    public void action(int retrying);
}

呼び出し側では繰り返したい処理を Action の action メソッド内に実装します。関数型インタフェイスとなっているので Lambda 式を使って記述可能です。

attempt()
public void attempt() {
    for (int i = 0; i < maxRetry; i++) {
        try {
            action.action(i);
            return;
        } catch (final Exception e) {
            if (!suppressWarning) {
                e.printStackTrace();
            }
            sleep();
        }
    }
}

attempt() メソッドでは受け取った Command を実行します。何も起こらなければ試行を終了し、例外をキャッチしたら intervalMs で指定したミリ秒分停止して再度の試行を実施します。


使い方

git clone & gradle jar

$ git clone https://github.com/toastkidjp/retry_handler.git

$ gradle jar
$ mv build/libs/retry_handler-0.0.1.jar

ビルドパスに「retry_handler-0.0.1.jar」を含め、ソースコード上で import する

import jp.toastkid.libs.retry.Retry;

使う

static メソッドを呼ぶ方法とインスタンスを生成して使う方法と、2種類用意しました。

static メソッドで使う

use_static
Retry.attempt((i) -> {/* 繰り返したい処理 */}, 2, 1000L);

インスタンスを生成して使う

ありがちですが build() してから attempt() を呼び出すのを忘れないでください。

use_by_instance
new Retry.Builder()
    .setAction((i) -> {/* 繰り返したい処理 */)
    .setMaxRetry(3)
    .setIntervalMs(1000L)
    .build()
    .attempt();

感想

元の記事のように Runnable で実装した方が別スレッドでの実行等の拡張がやりやすくなってよかったかもしれません。

7
10
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
10