本記事は TechHarmony Advent Calendar 2024 12/19付の記事です。 |
皆さんこんにちは。UGです。
忙しくない日だからと資格試験を申し込んだ25日がクリスマスであることを上司に指摘されて思い出した悲しい人間です。
皆さんは良いクリスマスが過ごせそうでしょうか?
自分はせめて合格がクリスマスプレゼントになるように頑張りたいと思います。。。
さて本題ですが、AWS Step Functionsを利用していてタイムアウトをちゃんと設定しないといけないなと思った出来事があり、タイムアウトの設定について調査・検証をしたのでその結果をまとめてみました。
背景
Choiceステートの分岐を利用したループ処理があるStep Functionsの検証をしていました。(以下はあくまでイメージ図です)
そんな時、ある条件下で無限ループが発生してしまうことを確認しました。
無限ループを放置してしまうと、もちろんその分の料金が発生してしまいます。(無限ループによって物凄い課金が発生したという記事も…)
ですので、ちゃんとタイムアウトを設定して思わぬ無限ループが発生した場合にタイムアウトさせる、といった処理が必要となります。
そのため、Step Functionsのオプション設定として存在する『TimeoutSeconds』と『TimeoutSecondsPath』について調査・検証をしてみました。
TimeoutSeconds
まず先に調査・検証結果を述べますが、TimeoutSecondsは
- ステートマシン全体
- アクションステート
の2つに設定することができ、
『ステートマシン全体』に設定した場合は、『ステートマシンが実行開始されてから終了するまでのタイムアウト値』となり、
『アクションステート』に設定した場合は、『アクションステートが実行開始されてから終了するまでのタイムアウト値』となります。
また、
『ステートマシン全体』に設定してタイムアウトが発生した場合は、ステータスは『タイムアウト』となり、
『アクションステート』に設定してタイムアウトが発生した場合は、ステータスは『失敗』となります。
では、各設定についてご説明していきます。
『ステートマシン全体』に設定した場合
ステートマシン全体に設定するには、[ワークフロー]フォームパネル → [TimeoutSeconds – オプション] で設定ができます。
Waitステートでタイムアウトが発生して停止されました。
Lambdaステートでタイムアウトが発生してキャンセルされました。
しかし、ステートマシンはキャンセルされているため、Lambdaの実行結果の戻り値はステートマシンには返されません。
『アクションステート』に設定した場合
アクションステートに設定するには、アクションステートを選択した場合に表示されるフォームパネル → [エラー処理]タブ → [TimeoutSeconds – オプション] → [TimeoutSecondsを入力]で設定ができます。
まずはTimeoutSecondsに1秒を設定して実行してみます。
Lambdaステートでタイムアウトが発生して失敗しました。
ステータスとしては『失敗』と表示されていました。
[エラー処理]タブで設定していることから、タイムアウトというよりもエラーとして処理をするために、ステータスが『失敗』となるのだと思います。おそらく。
今回もLambdaのログを確認してみました。
結果、「Hello」が記録されていたのでLambdaは最後まで実行されていることがわかります。
こちらもLambdaの実行時間に干渉しないことは同じのようです。
次にTimeoutSecondsを6秒に、またLambdaの後に5秒待機するWaitステートを追加して、TimeoutSecondsがLambdaステートのタイムアウト値であることを確認します。
問題なく成功し、今回設定したTimeoutSecondsは設定したアクションステートのタイムアウト時間であることがわかりました。
TimeoutSecondsPath
TimeoutSecondsPathは、入力データからタイムアウト時間を動的に取得することができます。利用例としては、Step Functionsでデータ処理を実施していて、データのサイズごとにタイムアウト時間を変更したいなどのシナリオで利用されるかと思います。
TimeoutSecondsPathは、アクションステートに設定することができるため、静的か動的かの違い以外はアクションステートに設定するTimeoutSecondsと同じ結果になります。
つまり、TimeoutSecondsPathを設定してタイムアウトが発生した場合は、ステータスは『失敗』となります。
では、実際に設定して試してみます。
TimeoutSecondsPathは、アクションステートを選択した場合に表示されるフォームパネル → [エラー処理]タブ → [TimeoutSeconds – オプション] → [実行時に、状態入力からTimeoutSecondsを取得]で設定できます。
設定値としてJSONPathを設定する必要があるため、今回は [$.TimeoutSecondsPath] を設定し、実行時の入力データとして”TimeoutSecondsPath”:1を与え実行します。
Lambdaステートでタイムアウトが発生して失敗しました。
ステータスとしては『失敗』と表示されていました。
ログは割愛しますがLambdaの実行についてもTimeoutSecondsと同様の結果でした。
注意点
「TimeoutSeconds」と「TimeoutSecondsPath」を設定する際の注意点を以下にまとめますので利用の際は気を付けてください。
- 「TimeoutSeconds」と「TimeoutSecondsPath」共にタイムアウト値は正の整数(0は含めない)であること
- 同じアクションステートに設定できるのは「TimeoutSeconds」か「TimeoutSecondsPath」どちらかのみ
※以下の図のように「TimeoutSeconds」と「TimeoutSecondsPath」を組み合わせることは可能
HTTPタスクのタイムアウトは、「TimeoutSeconds」や「TimeoutSecondsPath」の値がHTTPタスクのタイムアウトの値を超えた場合でも最大60秒(例:TimeoutSecondsを120秒で設定していたとしてもHTTPタスクは60秒でタイムアウトする)
タイムアウトをEventBridgeで取得するには
タイムアウトを設定したのならもちろんタイムアウトが発生した際に通知させたり、自動的にエラーハンドリングさせたりしたいと思うはずです。というか必ずすべきだと思います。
なので、EventBridgeでStep Functionsのエラー情報を取得する方法を簡単にご紹介します。
方法は簡単で、以下のようにEventBridgeのイベントパターンにおいて、[特定のステータス] を選択し、取得したいステータスを選択するだけです。
各ステータスは以下の通りです。
RUNNING・・・ステートマシンが現在実行中の場合
SUCCESSDED・・・ステートマシンが正常に完了した場合
FAILED・・・ステートマシンがエラーによって失敗した場合
TIMED_OUT・・・ステートマシンの実行が設定された時間を超えてしまったため、タイムアウトして終了した場合
ABORTED・・・ステートマシンの実行が中断された場合
何か問題が発生した時で考えると、『FAILED』、『TIMED_OUT』、『ABORTED』の3つを選択しておけば問題ないかと思います。
もし絞りたいといった場合は、本記事でお話した通りタイムアウトでもステータスが『失敗』となる場合があるため、ステータスの選択には十分に注意してください。
まとめ
調査を開始する前は、TimeoutSecondsが「ステートマシン全体の実行時間のタイムアウト」しかないと思っていたので、エラー処理のタブにTimeoutSecondsがあったときは???でした。かつTimeoutSecondsという名前でありながらステータスが「失敗」と表示されたときも???でした笑
同じように考えてしまう人がいらっしゃるのではないかと思いますので、本記事が皆様の助けになれば嬉しい限りです。
最後までお読みいただきありがとうございました!!