我有一个像这样的lambda函数:
import boto3
import os
import json
step_functions = boto3.client('stepfunctions')
workers_topic = boto3.resource('sns').Topic(os.environ.get("WORKERS_TOPIC_ARN"))
def test_push_to_workers_sns(event, context):
activity_response = \
step_functions.get_activity_task(
activityArn=os.environ.get("ACKNOWLEDGE_ACTIVITY_ARN"),
workerName='test_push_to_workers_sns'
)
task_token, input_ = activity_response['taskToken'], activity_response['input']
print(f"Task token is {task_token}")
print(f"Input is {input}")
if not task_token:
print("No activity found")
return
workers_topic.publish(Message="blah blah")
当我开始执行我所拥有的步骤功能并且它到达活动时,我反复检查在我的终端上运行aws stepfunctions get-activity-task --activity-arn <ACKNOWLEDGE_ACTIVITY_ARN>
会返回一个taskToken和输入都是正确的。然而,无论活动是否正在运行,这个lambda函数似乎总是超时(我已经将我的超时值设置为lambda函数的1分15秒,以及步骤函数的活动状态&#39;超时1小时)
答案 0 :(得分:1)
我使用以下CloudFormation模板检查了这个案例并且它可以工作:
AWSTemplateFormatVersion: "2010-09-09"
Description: Stack creating AWS Step Functions state machine and lambda function calling GetActivityTask.
Resources:
LambdaFunction:
Type: AWS::Lambda::Function
Properties:
Handler: "index.handler"
Role: !GetAtt LambdaExecutionRole.Arn
Code:
ZipFile: |
import boto3
import os
import json
step_functions = boto3.client('stepfunctions')
workers_topic = boto3.resource('sns').Topic(os.environ.get("WORKERS_TOPIC_ARN"))
def handler(event, context):
activity_response = step_functions.get_activity_task(
activityArn=os.environ.get("ACKNOWLEDGE_ACTIVITY_ARN"),
workerName='test_push_to_workers_sns'
)
if 'taskToken' not in activity_response:
return
task_token, task_input = activity_response['taskToken'], activity_response['input']
print(f"Task token is {task_token}")
print(f"Input is {input}")
workers_topic.publish(Message="blah blah")
step_functions.send_task_success(
taskToken=task_token,
output=task_input
)
Runtime: "python3.6"
Timeout: 25
Environment:
Variables:
WORKERS_TOPIC_ARN: !Ref WorkersTopic
ACKNOWLEDGE_ACTIVITY_ARN: !Ref AcknowledgeActivity
StateMachine:
Type: AWS::StepFunctions::StateMachine
Properties:
RoleArn: !GetAtt StatesExecutionRole.Arn
DefinitionString: !Sub
- >
{
"Comment": "State Machine for GetActivityTask testing purposes.",
"StartAt": "FirstState",
"States": {
"FirstState": {
"Type": "Task",
"Resource": "${ACKNOWLEDGE_ACTIVITY_ARN}",
"End": true
}
}
}
- ACKNOWLEDGE_ACTIVITY_ARN: !Ref AcknowledgeActivity
AcknowledgeActivity:
Type: AWS::StepFunctions::Activity
Properties:
Name: !Sub ${AWS::AccountId}-AcknowledgeActivity
WorkersTopic:
Type: AWS::SNS::Topic
LambdaExecutionRole:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Principal:
Service:
- lambda.amazonaws.com
Action:
- sts:AssumeRole
Path: "/"
Policies:
- PolicyName: StepFunctionsAccess
PolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Action:
- states:GetActivityTask
- states:SendTaskFailure
- states:SendTaskSuccess
Resource: arn:aws:states:*:*:*
- PolicyName: SNSAccess
PolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Action:
- SNS:Publish
Resource: arn:aws:sns:*:*:*
StatesExecutionRole:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Principal:
Service:
- !Sub states.${AWS::Region}.amazonaws.com
Action: sts:AssumeRole
Path: "/"
Policies: []
我从Step Functions控制台手动创建了执行,并从Lambda控制台手动执行了Lambda。
请记住,使用taskToken
GetActivityTask
后,与之相关的执行正在等待响应(SendTaskSuccess
或SendTaskFailure
),直到达到超时(默认为非常长)。因此,如果您在此之前已经取得令牌,则GetAcitivtyTask
无法执行。您可以在Step Functions控制台中查找执行状态,查看特定执行的事件。
从SendTaskSuccess
获取令牌后,您应该从代码中调用SendTaskFailure
或GetActivityTask
(否则执行将一直挂起,直到达到超时或停止)。
除了原始问题:GetActivityTask
不适合从Lambda调用。您可以将Lambda Function作为资源传递给状态机(而不是活动),并在执行到达指定状态时调用它(处理程序中的event
将包含执行状态)。活动应仅用于专用机器(EC2,ECS)上的长时间运行作业。我还应该指出GetActivityTask
次呼叫存在服务限制(25个RPS,桶大小为1000),基于Lambda的状态基本上仅受到转换计数限制(每秒400个,桶大小为800)的限制。您可以在此处详细了解步骤功能限制:https://docs.aws.amazon.com/step-functions/latest/dg/limits.html