StepFunction リトライ時の待機時間

渡辺です。

StepFunction便利です。 Lambda実行時のエラーハンドリングやリトライを外部定義したり、一定期間後に処理をしたりと至れり尽くせり。 ローカル実行用環境も発表されたようで、いよいよStepFunction時代の到来ではないでしょうか?

今回は公式ドキュメントが難解で一発で理解できかったため、リトライの仕様について噛み砕いて説明します。

デフォルトの待機時間

デフォルトでは3回のリトライを行います。 1回目は1秒後、2回目は最初の実行から3秒後、3回目は最初の実行から7秒後です。

リトライのパラメータ

リトライには3つのオプションパラメータがあります。 IntervalSeconds , MaxAttempts , BackoffRate です。

"Retry" : [
    {
      "ErrorEquals": [ "States.Timeout" ],
      "IntervalSeconds": 3,
      "MaxAttempts": 4,
      "BackoffRate": 1.5
    }
]

この場合は、「3 秒、4.5 秒、6.75 秒、および 10.125 秒待機した後で 4 回の再試行」となっています。 この待機時間はトータル待機時間で、次の計算式で求められます。

  • 初回) IntervalSeconds 秒
  • 2回目以降) IntervalSeconds + BackoffRateの(試行回数-1)乗

ばらすと解りやすいです。

  1. 3
  2. 4.5 = 3 + 1.5
  3. 6.75 = 4.5 + 1.5 * 1.5
  4. 10.125 = 6.75 + 1.5 * 1.5 * 1.5

BackoffRateを1にすれば、1秒毎のリトライになりますし、2にすると2,4,8,16秒のインターバル。 3にすれば、3,9,27秒、5だと、5,25秒、このあたりのインターバルがあると色々なユースケースに対応できるでしょう。

例えば、1回目は少し時間を空けて、リトライするけど30秒くらいで諦めるなら、

"Retry" : [
    {
      "ErrorEquals": [ "States.Timeout" ],
      "IntervalSeconds": 5,
      "MaxAttempts": 3,
      "BackoffRate": 5
    }
]

これで5, 10, 35秒後のリトライです。

まとめ

計算面倒なのでワンライナーをおいておきますね。

$ node -e '((i,m,b)=>{for(let w=i,c=0;c<m;c++){console.log(w+=(c==0?0:b**c))}})(3,4,1.5)'
3
4.5
6.75
10.125
$ node -e '((i,m,b)=>{for(let w=i,c=0;c<m;c++){console.log(w+=(c==0?0:b**c))}})(5,3,5)'
5
10
35