如何通过AWS Step Functions自身逻辑判断执行状态并控制依赖执行?
AWS Step Functions 依赖执行控制与输出转换方案
问题背景
我们每日导入两个数据集(dataset A和dataset B),其中dataset A可能并非每日都会出现;这两个数据集分别触发独立的AWS Step Functions;处理dataset B的Step Function B必须等到处理dataset A的Step Function A停止运行或从未运行后才能执行,以确保Step Function B使用最新数据。
当前调用ListExecutions获取的执行历史输出如下:
{ "executions": [ { "executionArn": "arn:aws:states:us-west-2:123456789:execution:StateMachineA12345-12345-12345:1234-1", "stateMachineArn": "arn:aws:states:us-west-2:123456789:stateMachine:StateMachineA12345-12345-12345", "name": "1234-1", "status": "RUNNING", "startDate": "2023-02-27T15:21:22.205000-08:00", "stopDate": "2023-02-27T15:28:11.358000-08:00" }, { "executionArn": "arn:aws:states:us-west-2:123456789:execution:StateMachineA12345-12345-12345:1234-2", "stateMachineArn": "arn:aws:states:us-west-2:123456789:stateMachine:StateMachineA12345-12345-12345", "name": "1234-2", "status": "ABORTED", "startDate": "2023-02-27T15:19:55.739000-08:00", "stopDate": "2023-02-27T15:21:11.924000-08:00" }, { "executionArn": "arn:aws:states:us-west-2:123456789:execution:StateMachineA12345-12345-12345:1234-3", "stateMachineArn": "arn:aws:states:us-west-2:123456789:stateMachine:StateMachineA12345-12345-12345", "name": "1234-3", "status": "COMPLETED", "startDate": "2023-02-27T15:18:45.228000-08:00", "stopDate": "2023-02-27T15:19:20.651000-08:00" }, { "executionArn": "arn:aws:states:us-west-2:123456789:execution:StateMachineA12345-12345-12345:1234-4", "stateMachineArn": "arn:aws:states:us-west-2:123456789:stateMachine:StateMachineA12345-12345-12345", "name": "1234-4", "status": "FAILED", "startDate": "2023-02-27T15:18:30.145000-08:00", "stopDate": "2023-02-27T15:18:34.315000-08:00" } ] }
需要解决两个问题:
- 能否仅通过Step Functions逻辑,添加
ListExecutions步骤并等待直到State Machine A的执行状态不等于RUNNING? - 能否仅通过Step Functions逻辑,将上述
ListExecutions的输出转换为{"status": "RUNNING"}或{"status": "NOT RUNNING"}结构?
问题1:实现等待State Machine A完成或未运行的逻辑
完全可以通过Step Functions内置状态实现,无需Lambda,核心流程如下:
核心步骤
- 调用
ListExecutions时过滤运行中执行:指定State Machine A的ARN,设置StatusFilter: "RUNNING",直接返回正在运行的执行(如果存在),避免处理全量历史数据。 - 循环检查直到无运行中执行:用
Choice状态判断返回的executions数组长度:- 数组长度>0:进入
Wait状态(比如等待30秒),然后回到ListExecutions步骤重复检查。 - 数组长度=0(包括从未运行过的情况):直接执行State Machine B的后续逻辑。
- 数组长度>0:进入
示例状态机片段
{ "States": { "CheckSMARunningStatus": { "Type": "Task", "Resource": "arn:aws:states:::aws-sdk:states:listExecutions", "Parameters": { "StateMachineArn": "arn:aws:states:us-west-2:123456789:stateMachine:StateMachineA12345-12345-12345", "StatusFilter": "RUNNING" }, "Next": "HasRunningExec?" }, "HasRunningExec?": { "Type": "Choice", "Choices": [ { "Variable": "$.executions.length()", "NumericGreaterThan": 0, "Next": "Wait30Seconds" } ], "Default": "StartSMBProcessing" }, "Wait30Seconds": { "Type": "Wait", "Seconds": 30, "Next": "CheckSMARunningStatus" }, "StartSMBProcessing": { "Type": "Pass", "End": true // 替换为State Machine B的实际处理逻辑 } } }
问题2:转换ListExecutions输出为指定状态结构
同样无需Lambda,通过Step Functions的Task、Choice和Pass状态即可实现,推荐两种方法:
方法1:基于过滤后的运行中执行判断(高效优先)
直接利用ListExecutions的StatusFilter参数减少数据量,再判断输出:
- 调用
ListExecutions筛选出State Machine A的所有RUNNING执行。 - 用
Choice状态检查executions数组长度:- 长度>0:通过
Pass状态输出{"status": "RUNNING"}。 - 长度=0:通过
Pass状态输出{"status": "NOT RUNNING"}。
- 长度>0:通过
示例状态机片段
{ "States": { "FetchRunningExecs": { "Type": "Task", "Resource": "arn:aws:states:::aws-sdk:states:listExecutions", "Parameters": { "StateMachineArn": "arn:aws:states:us-west-2:123456789:stateMachine:StateMachineA12345-12345-12345", "StatusFilter": "RUNNING" }, "Next": "ResolveStatus" }, "ResolveStatus": { "Type": "Choice", "Choices": [ { "Variable": "$.executions.length()", "NumericGreaterThan": 0, "Next": "ReturnRunningStatus" } ], "Default": "ReturnNotRunningStatus" }, "ReturnRunningStatus": { "Type": "Pass", "Result": { "status": "RUNNING" }, "ResultPath": "$", "End": true }, "ReturnNotRunningStatus": { "Type": "Pass", "Result": { "status": "NOT RUNNING" }, "ResultPath": "$", "End": true } } }
方法2:处理全量执行列表(适用于必须获取全量历史的场景)
如果无法使用StatusFilter,可以通过Map和Filter状态提取并筛选状态:
- 用
Map遍历全量executions数组,提取每个执行的status字段。 - 用
Filter状态筛选出值为RUNNING的条目。 - 判断筛选后的数组长度,输出对应状态结构。
这种方法步骤更多,性能不如方法1,仅在特殊场景下使用。
内容的提问来源于stack exchange,提问作者Justin Bates
相关产品推荐
相关产品推荐

