Starting a StepFunction and exiting doesn't trigger execution

谁都会走 提交于 2019-12-24 19:46:39

问题


I have Lambda function tranportKickoff which receives an input and then sends/proxies that input forward into a Step Function. The code below does run and I am getting no errors but at the same time the step function is NOT executing.

Also critical to the design, I do not want the transportKickoff function to wait around for the step function to complete as it can be quite long running. I was, however, expecting that any errors in the calling of the Step Function would be reported back synchronously. Maybe this thought is at fault and I'm somehow missing out on an error that is thrown somewhere. If that's the case, however, I'd like to find a way which is able to achieve the goal of having the kickoff lambda function exit as soon as the Step Function has started execution.

note: I can execute the step function independently and I know that it works correctly

  const stepFn = new StepFunctions({ apiVersion: "2016-11-23" });
  const stage = process.env.AWS_STAGE;
  const name = `transport-steps ${message.command} for "${stage}" environment at ${Date.now()}`;
  const params: StepFunctions.StartExecutionInput = {
    stateMachineArn: `arn:aws:states:us-east-1:999999999:stateMachine:transportion-${stage}-steps`,
    input: JSON.stringify(message),
    name
  };
  const request = stepFn.startExecution(params);
  request.send();
  console.info(
    `startExecution request for step function was sent, context sent was:\n`,
    JSON.stringify(params, null, 2)
  );

  callback(null, {
    statusCode: 200
  });

I have also checked from the console that I have what I believe to be the right permissions to start the execution of a step function:

I've now added more permissions (see below) but still experiencing the same problem:

  • 'states:ListStateMachines'
  • 'states:CreateActivity'
  • 'states:StartExecution'
  • 'states:ListExecutions'
  • 'states:DescribeExecution'
  • 'states:DescribeStateMachineForExecution'
  • 'states:GetExecutionHistory'

回答1:


Ok I have figured this one out myself, hopefully this answer will be helpful for others:

First of all, the send() method is not a synchronous call but it does not return a promise either. Instead you must setup listeners on the Request object before sending so that you can appropriate respond to success/failure states.

I've done this with the following code:

const stepFn = new StepFunctions({ apiVersion: "2016-11-23" });
const stage = process.env.AWS_STAGE;
const name = `${message.command}-${message.upc}-${message.accountName}-${stage}-${Date.now()}`;
const params: StepFunctions.StartExecutionInput = {
  stateMachineArn: `arn:aws:states:us-east-1:837955377040:stateMachine:transportation-${stage}-steps`,
  input: JSON.stringify(message),
  name
};
const request = stepFn.startExecution(params);
// listen for success
request.on("extractData", req => {
  console.info(
    `startExecution request for step function was sent and validated, context sent was:\n`,
    JSON.stringify(params, null, 2)
  );

  callback(null, {
    statusCode: 200
  });
});
// listen for error
request.on("error", (err, response) => {
  console.warn(
    `There was an error --  ${err.message} [${err.code}, ${
      err.statusCode
    }] -- that blocked the kickoff of the ${message.command} ITMS command for ${
      message.upc
    } UPC, ${message.accountName} account.`
  );
  callback(err.statusCode, {
    message: err.message,
    errors: [err]
  });
});
// send request
request.send();

Now please bear in mind there is a "success" event but I used "extractData" to capture success as I wanted to get a response as quickly as possible. It's possible that success would have worked equally as well but looking at the language in the Typescript typings it wasn't entirely clear and in my testing I'm certain that the "extractData" method does work as expected.

As for why I was not getting any execution on my step functions ... it had to the way I was naming the function ... you're limited to a subset of characters in the name and I'd stepped over that restriction but didn't realize until I was able to capture the error with the code above.




回答2:


For anyone encountering issues executing state machines from Lambda's make sure the permission 'states:StartExecution' is added to the Lambda permissions and the regions match up.

Promise based version:

import { StepFunctions } from 'aws-sdk';

const clients = {
  stepFunctions: new StepFunctions();
}

const createExecutor = ({ clients }) => async (event) => {
  console.log('Executing media pipeline job');

  const params = {
    stateMachineArn: '<state-machine-arn>',
    input: {},
    name: 'new-job',
  };

  const result = await stepFunctions.startExecution(params).promise();
  // { executionArn: "string", startDate: number }

  return result;
};

const startExecution = createExecutor({ clients });

// Pass in the event from the Lambda e.g S3 Put, SQS Message
await startExecution(event);

Result should contain the execution ARN and start date (read more)



来源:https://stackoverflow.com/questions/49244134/starting-a-stepfunction-and-exiting-doesnt-trigger-execution

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!