Retryable
retry_count = 0;
tries = 3;
begin
do_something
rescue => e
retry_count += 1;
raise e if retry > tries;
sleep 1
retry
end
これが、
Retryable.retry(:tries => 3) { do_something }
と書ける
n回失敗したらログを書いて終了
retry_count = 0;
tries = 3;
begin
do_something
rescue => e
retry_count += 1;
if retry > tries
log("die")
exit 1
end
sleep 1
retry
end
Retryableのオプションには、rescue節の中の処理を書くexception_cb
コールバックと、ensure節の処理を書くensure
コールバックがある。このうちensure
コールバックを使う。
Retryable.retry(:tries => n, :ensure => Proc.new {|tries| ...}) {...}
引数だけではn回目に成功した場合とn回失敗した場合の区別がつかない。が、$!に例外が設定されているかどうかで区別できる
ensure_cb = Proc.new do |tries|
if $!
log("die")
exit 1
end
end
ただし、コールバックの実行が終わったら例外が発生するので、exitする場合でないと使えない。
別案
#案1
#一回多く実行させてそれを拾う。:tries => n + 1に注意
Retryable.retry(:tries => n + 1) do |tries, exception|
if(:tries >= n)
log("die")
exit
end
do_something
end
#案2
#最終回失敗したら例外が出るのでbeginで拾う
begin
Retryable.retry(:tries => n) { do_something }
rescue
log("die")
exit
end
どれもいまいちすっきりしない。
最終回の試行が失敗した後に呼ばれるfinally
コールバックと、例外を送出しないオプションを追加するPRを出してる人はいるのだけどマージされていない。