概要
「Ruby の retry-handler が激しく便利そうなので Java で実装してみた」を読んで、そういう便利なものがあると知りました。せっかくなので、私も勉強を兼ねて見よう見まねで実装してみました。
リトライハンドラの機能
例外が発生しうる処理をx回試行します。例外が発生しなければ1回で終了し、発生した場合は最大指定回数繰り返します。
HTTP アクセス等の、例外が発生しても成功するまで何回か繰り返してほしい処理で役に立ちます。
実装
Command を受け取るだけの interface を定義しておきます。
public interface Action {
public void action(int retrying);
}
呼び出し側では繰り返したい処理を Action の action メソッド内に実装します。関数型インタフェイスとなっているので Lambda 式を使って記述可能です。
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 メソッドで使う
Retry.attempt((i) -> {/* 繰り返したい処理 */}, 2, 1000L);
インスタンスを生成して使う
ありがちですが build() してから attempt() を呼び出すのを忘れないでください。
new Retry.Builder()
.setAction((i) -> {/* 繰り返したい処理 */)
.setMaxRetry(3)
.setIntervalMs(1000L)
.build()
.attempt();
感想
元の記事のように Runnable で実装した方が別スレッドでの実行等の拡張がやりやすくなってよかったかもしれません。