Wronski
Wronski

Reputation: 1596

Why does my await lambda.invoke function invoke lambda multiple times?

Currently

I have a lambdaX that invokes another lambdaY.

Lambda X:

"use strict";

const AWS = require('aws-sdk');
AWS.config.region = 'ap-southeast-2';
var lambda = new AWS.Lambda();

exports.handler = async (event) => {

  //the final return
  var dataToSave = []

  //data to be added to array
  let returnLoad;

  var params = {
    FunctionName: 'lambdaY', // the lambda function we are going to invoke
    InvocationType: 'RequestResponse',
    LogType: 'Tail', //Set to Tail to include the execution log in the response.
  };

  try {
    await lambda.invoke(params, function(err, data) {
      if (err) {
        console.log("Error");
        console.log(err, err.stack);
      } else {
        console.log("Success");
        console.log(data);
        returnLoad = data.Payload;
      }
    }).promise();

    dataToSave.push(returnLoad);

  } catch (err) {
      console.log('some error occurred...');
  }

  const response = {
      statusCode: 200,
      body: JSON.stringify(dataToSave)
  };
  return response;
}

Lambda Y:

exports.handler = async (event) => {
    const response = {
        statusCode: 200,
        body: JSON.stringify('Hello from Lambda!'),
    };
    return response;
};

Problem

For some reason lambdaY invokes 2+ times whenever I invoke lambdaX. Note, lambdaX gets the correct response back, but I want to avoid unnecessarily invoking lambdaY multiple times.

What do I need to change in my code? (or lambda configuration)

Logs:

Note: 2 logs of lambdaY being invoked at exactly the same time.

enter image description here

Note: LambdaX results are healthy and as expected. There isn't a duplicate log.

enter image description here

Upvotes: 3

Views: 1164

Answers (1)

jarmod
jarmod

Reputation: 78603

Your code is misusing the AWS SDK. Specifically, it is using both the callback and promise features simultaneously. It should use one or the other, but not both.

I would change it to use just the promise (and obviously add some error handling to this):

const data = await lambda.invoke(params).promise();
const returnLoad = data.Payload;

The reason that lambda.invoke(params, callback).promise() sends 2 requests is as follows:

  1. within the AWS SDK generally, a call to service.action(params) returns an AWSRequest object on which you have to call .send() for the API request to actually be sent
  2. a call to service.action(params, callback) executes the following code: if (callback) request.send(callback), so the presence of the callback function sends the API request
  3. the .promise() method's code "sends the request and returns a promise", so it also sends the API request

And that's why the API call happens twice if callback and promise() are both present.

Upvotes: 9

Related Questions