如何在Lambda函数中为回调返回型Step Function使用Heartbeat?
当Lambda函数作为Step Functions状态机中的任务时,需通过返回token让状态机继续执行,针对try/catch块中的SendTaskHeartbeatCommand、SendTaskSuccessCommand和SendTaskFailureCommand,存在以下疑问:
SendTaskHeartbeatCommand与SendTaskSuccessCommand的调用顺序SendTaskHeartbeatCommand的必填参数- 是否需在catch块中添加
SendTaskHeartbeatCommand,若需要则调用顺序如何
当前代码:
try { const magentoCallResponse = await axios(requestObject); await stepFunctionClient.send(new SendTaskHeartbeatCommand(taskToken)); await stepFunctionClient.send(new SendTaskSuccessCommand({output: JSON.stringify(magentoCallResponse.data), taskToken})); return magentoCallResponse.data; } catch (err: any) { console.log("ERROR", err); await stepFunctionClient.send(new SendTaskFailureCommand({error: JSON.stringify("Error Sending Data into Magento"), taskToken})); return false; }
1. SendTaskHeartbeatCommand与SendTaskSuccessCommand的调用顺序
SendTaskHeartbeatCommand的作用是向Step Functions发送心跳,告知状态机任务仍在正常运行,避免因超时被标记为失败。正确的调用逻辑是:
- 如果任务执行时间较长(超过Step Functions任务的超时阈值,默认30秒,可配置),需要在任务执行过程中定期发送心跳;
- 任务成功完成后,再调用
SendTaskSuccessCommand结束任务。
你当前代码中先调用心跳再调用成功命令的顺序本身没问题,但如果你的axios请求是短时间就能完成的,其实没必要发送心跳——心跳只针对耗时较长的场景。另外要注意:发送SendTaskSuccessCommand后再发送心跳是无效的,因为任务已经进入完成状态。
2. SendTaskHeartbeatCommand的必填参数
在AWS SDK v3中,SendTaskHeartbeatCommand的唯一必填参数是taskToken,也就是Step Functions调用Lambda时传入的任务令牌(通常从Lambda事件的taskToken字段获取)。
你之前困惑的input参数是可选的,仅用于向状态机传递中间状态数据,不是必须项。正确的调用方式有两种:
// 方式1:传入包含taskToken的对象 await stepFunctionClient.send(new SendTaskHeartbeatCommand({ taskToken })); // 方式2:直接传入taskToken(SDK内部会自动处理为对象格式) await stepFunctionClient.send(new SendTaskHeartbeatCommand(taskToken));
3. catch块中是否需要添加SendTaskHeartbeatCommand?
不需要。当任务抛出异常进入catch块时,说明任务已经执行失败,此时直接调用SendTaskFailureCommand告知状态机任务失败即可。
心跳的作用是维持任务的"活跃"状态,任务失败后发送心跳没有意义——状态机收到失败命令后会立即终止当前任务,后续的心跳请求会被直接忽略。
另外建议优化catch块的错误处理,把具体错误信息加入cause字段,方便后续排查:
await stepFunctionClient.send(new SendTaskFailureCommand({ error: "MagentoRequestFailed", cause: JSON.stringify(err.message || err), taskToken }));
内容的提问来源于stack exchange,提问作者Lloukas

