はじめに
エラーを吐く可能性のある処理を含むスクリプトで,何度か繰り返してから,それでもダメなら終了したいという場面にでくわしました.
どうやら「リトライ処理」というらしいですね.(初めて知りました)
リトライ処理
今回使用する言語はPythonで,良い方法は無いかと調べたところ,以下の候補がありました.
-
for-else
文 -
Tenacity
ライブラリ -
Retrying
ライブラリ -
retry
ライブラリ
今回,選択したのはTenacity
ライブラリを用いる方法です.
言語ネイティブで実装できるならそれに越したことはないという派閥の方が居ることは承知の上で,個人的には(研究レベルで使うなら)車輪の再発明は避けるべきであるという派閥のため,ライブラリを用いることにしました.
また,Retrying
とretry
は更新が停止しているため,今回の候補から除外しました.
Tenacity
ライブラリ
ライブラリの公式ドキュメントを以下に貼っておきます.
詳細はこちらを参照してもらえればと思いますが,以下の簡単なサンプルコードから派生させる形で示してみたいと思います.
def raise_error_randomly():
'''
ランダムにエラーを発生する関数
'''
pass
raise_error_randomly()
エラー発生時に繰り返す
エラー発生時に成功するまで繰り返す処理を追加します.
from tenacity import retry
@retry
def raise_error_randomly():
'''
ランダムにエラーを発生する関数
'''
pass
raise_error_randomly()
デコレータをつけるだけで,既にある関数にリトライ処理を追加することができました.簡単で良いですね.
繰り返し回数を指定する
上記のままであれば,ひたすら繰り返し処理が走ります.しかし,ある一定回数処理をおこない,それでも正常終了しなければエラーを出したいということもあると思います.
from tenacity import retry, stop_after_attempt
@retry(stop=stop_after_attempt(3))
def raise_error_randomly():
'''
ランダムにエラーを発生する関数
'''
pass
raise_error_randomly()
stop_after_attempt
の引数に繰り返し回数を指定します.上記の例であれば3回処理をおこない,それでも失敗するとエラーを出力します.
繰り返すまでの待ち時間を設定する
繰り返し処理をおこなう際に,少し待ってから再度実行するようにしたいことも多いかなと思います.そうした需要にも対応してくれています.
from tenacity import retry, stop_after_attempt, wait_fixed
@retry(stop=stop_after_attempt(3), wait=wait_fixed(10))
def raise_error_randomly():
'''
ランダムにエラーを発生する関数
'''
pass
raise_error_randomly()
wait_fixed
の引数に,繰り返しまでの秒数を指定します.上記の例であれば10秒おきに実行されます.
最後に
いかがでしたでしょうか?
今回はリトライ処理の実装について,メモがてら記事にしてみました.
Tenacity
ライブラリには挙げたもの以外にも「〇〇秒以内に完了しなければリトライする」や「リトライ処理の条件を指定する」といった使い方もできるようです.