AWS Step Functions でランダムな待機時間を実装してみた。JSONata と JSONPath
はじめに
クラウド事業本部の梶原@福岡です。
今回は、AWS Step Functions で動的な待機時間を実装する方法について、JSONata と JSONPath の両方のアプローチをご紹介します。
テスト環境でのシミュレーションや、API呼び出しの間隔をランダム化させたい場合などに有用かと思います。
動的な待機時間が必要なケース
Step Functions のワークフローでは、特定の時間だけ処理を一時停止したい場合があります。
- API レート制限を回避するための待機時間
- テスト環境での実際の運用シナリオのシミュレーション
通常、Wait ステートでは固定の秒数や終了時刻を指定しますが、JSONata や JSONPath でランダム関数を使うことで動的に値を計算し、指定できます。
アプローチ1:JSONata を使用したランダム秒待機
JSONata は JSON データに対するクエリおよび変換言語です。
AWS Step Functions で JSONata のサポートが追加され、ステートマシン定義内で複雑な計算や変換が可能になりました。
最初はとっつきにくかったですが、JSONata最高です。
詳細は以下の公式ブログをご参照ください:
Simplifying developer experience with variables and JSONata in AWS Step Functions
ステートマシン定義(JSONata版)
{
"Comment": "A state machine with random wait time using JSONata",
"QueryLanguage": "JSONata",
"StartAt": "CalculateWaitSeconds",
"States": {
"CalculateWaitSeconds": {
"Type": "Pass",
"Next": "Wait",
"Assign": {
"waitSeconds": "{% ($random() * 60 + 1) ~> $floor() %}"
}
},
"Wait": {
"End": true,
"Seconds": "{% $waitSeconds %}",
"Type": "Wait"
}
}
}
JSONata版の解説
"QueryLanguage": "JSONata"
- ステートマシン全体で JSONata を使用することを宣言"waitSeconds": "{% ($random() * 60 + 1) ~> $floor() %}"
- ランダムな待機秒数を計算"Seconds": "{% $waitSeconds %}"
- 計算した値を使用して待機
JSONataの$random()
関数の詳細は公式ドキュメントをご参照ください。
AWSコンソール
アプローチ2:JSONPath を使用したランダム秒待機
JSONPath は従来から Step Functions でサポートされている式言語です。組み込み関数 States.MathRandom()
を使用して、ランダムな値を生成できます。
なお、JSONataが使えるようになったタイミングで、JSONPathでも変数が使えるようになっています。
ステートマシン定義(JSONPath版)
{
"Comment": "A state machine with random wait time using JSONPath",
"QueryLanguage": "JSONPath",
"StartAt": "CalculateWaitSeconds",
"States": {
"CalculateWaitSeconds": {
"Type": "Pass",
"Assign": {
"waitSeconds.$": "States.MathRandom(1, 60)"
},
"Next": "Wait"
},
"Wait": {
"Type": "Wait",
"End": true,
"SecondsPath": "$waitSeconds"
}
}
}
JSONPath版の解説
"QueryLanguage": "JSONPath"
- ステートマシン全体で JSONPath を使用することを宣言"waitSeconds.$": "States.MathRandom(1, 60)"
- 1〜60の範囲でランダムな整数を生成"SecondsPath": "$waitSeconds"
- 計算した値を使用して待機
States.MathRandom()
関数の詳細はAWS公式ドキュメントをご参照ください。
ポイント: 通常秒数を指定するSeconds
ではなく、SecondsPath
を使用します
AWSコンソール
実行結果
どちらのステートマシンも実行すると、以下のような流れになります:
CalculateWaitSeconds
ステートで、ランダムな待機秒数を計算し、waitSeconds
変数に代入Wait
ステートで、計算された秒数(waitSeconds)だけ待機- 実行が完了
AWS Management Console の Step Functions 実行履歴では、各ステートの入出力を確認できます。
実行時間もランダムな実行時間となっています。
まとめ
Step Functions では、JSONata と JSONPath の両方を使って動的な待機時間を実装できます。
なお、Step Functions の Wait ステートは、実は内部的には「アクティブに待機」しているわけではなく、指定された時間が経過したときに再開するようにスケジュールされます。Standard ワークフローの場合、課金もされませんので
待機したいときの相性が良いです。(Expressの場合は待機時間も課金されますのでご注意ください)
以下のCloudFormationテンプレートを使えば、これらの機能を簡単にご自分の環境にデプロイできますので、試してみてください。
CloudFormation テンプレート(JSONata版)
AWSTemplateFormatVersion: '2010-09-09'
Description: 'CloudFormation template for Step Functions with random wait using JSONata'
Resources:
RandomWaitStateMachineRole:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Principal:
Service: states.amazonaws.com
Action: 'sts:AssumeRole'
ManagedPolicyArns:
- 'arn:aws:iam::aws:policy/AWSXrayWriteOnlyAccess'
RandomWaitStateMachine:
Type: AWS::StepFunctions::StateMachine
Properties:
StateMachineName: RandomWaitStateMachine-JSONata
RoleArn: !GetAtt RandomWaitStateMachineRole.Arn
Definition:
Comment: A state machine with random wait time using JSONata
QueryLanguage: JSONata
StartAt: CalculateWaitSeconds
States:
CalculateWaitSeconds:
Type: Pass
Next: Wait
Assign:
waitSeconds: "{% ($random() * 60 + 1) ~> $floor() %}"
Wait:
End: true
Seconds: "{% $waitSeconds %}"
Type: Wait
StateMachineType: STANDARD
Outputs:
StateMachineArn:
Description: ARN of the Random Wait State Machine (JSONata)
Value: !Ref RandomWaitStateMachine
CloudFormation テンプレート(JSONPath版)
AWSTemplateFormatVersion: '2010-09-09'
Description: 'CloudFormation template for Step Functions with random wait using JSONPath'
Resources:
RandomWaitStateMachineRoleJSONPath:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Principal:
Service: states.amazonaws.com
Action: 'sts:AssumeRole'
ManagedPolicyArns:
- 'arn:aws:iam::aws:policy/AWSXrayWriteOnlyAccess'
RandomWaitStateMachineJSONPath:
Type: AWS::StepFunctions::StateMachine
Properties:
StateMachineName: RandomWaitStateMachine-JSONPath
RoleArn: !GetAtt RandomWaitStateMachineRoleJSONPath.Arn
Definition:
Comment: A state machine with random wait time using JSONPath
StartAt: CalculateWaitSeconds
States:
CalculateWaitSeconds:
Type: Pass
Assign:
waitSeconds.$: States.MathRandom(1, 60)
Next: Wait
Wait:
Type: Wait
End: true
SecondsPath: $waitSeconds
QueryLanguage: JSONPath
StateMachineType: STANDARD
Outputs:
StateMachineArnJSONPath:
Description: ARN of the Random Wait State Machine (JSONPath)
Value: !Ref RandomWaitStateMachineJSONPath