+7 votes
3.9k views
in Amazon Web Service by anonymous

I need to invoke aws lambda from another lambda asynchronously. i have a working code for synchronous calls.

exports.handler = (event, context, callback) => {
    var aws = require('aws-sdk');
    var lambda = new aws.Lambda({
        region: 'myregion' //change to your region
    });
    console.log("lambda invoke started");
    lambda.invoke({
        FunctionName: 'testLambda',
        Payload: JSON.stringify(event, null, 2) // pass params
    }, function (error, data) {
        if (error) {
            console.log("error");
            callback(null, 'hello world');
        }
        else {
            console.log("lambda invoke end");
            callback(null, 'hello world');
        }
    });
}

But in my case, 'testLambda' is a time taken function. Because i need to exit just after invoking the 'testLambda' function. Then code is updated like this

exports.handler = (event, context, callback) => {
    var aws = require('aws-sdk');
    var lambda = new aws.Lambda({
        region: 'myregion' //change to your region
    });
    console.log("lambda invoke started");
    lambda.invoke({
        FunctionName: 'testLambda',
        Payload: JSON.stringify(event, null, 2) // pass params
    });
    console.log("lambda invoke end");
    callback(null, 'hello world');
}

it returns message correctly . But my 'testLambda' function is not invoked(no cloud watch logs are generated for test lambda). what is the issue related with this code.

2 Answers

+7 votes
by

Per the Lambda invoke() documentation, you will see that by default the Lambda function is invoked using the RequestResponse invocation type. To invoke the function asynchronously you need to specify the Event invocation type, like so:

lambda.invoke({
    FunctionName: 'testLambda',
    InvocationType: 'Event',
    Payload: JSON.stringify(event, null, 2)
},function(err,data){});
+5 votes
by

I was working with the currently latest node.js 8.10 version in AWS Lambda.
The second lambda didn't execute (and the callback function was never called) until i used the async/await mechanism.
So the handler function must be async, and the 'lambda.invoke' call be wrapped with a Promise.

here is my working code:

function invokeLambda2(payload) {
    const params = {
        FunctionName: 'TestLambda2',
        InvocationType: 'Event',
        Payload: JSON.stringify(payload)
    };

    return new Promise((resolve, reject) => {

        lambda.invoke(params, (err,data) => {
            if (err) {
                console.log(err, err.stack);
                reject(err);
            }
            else {
                console.log(data);
                resolve(data);
            }
        });     
    });
}


exports.handler = async (event, context) => {
    const payload = {
        'message': 'hello from lambda1'
    };
    await invokeLambda2(payload);
    context.done();
};

Please notice that the handler doesn't wait for the second lambda to exit, only for it to be triggered and the callback function being called.

You could also return the Promise from within the handler, don't have to use await with a second function.

No need for any import when working with Promises and async/await, other than:

const AWS = require('aws-sdk');
const lambda = new AWS.Lambda();
Welcome to Kloudwise, where you can ask any AWS, Azure, GCP and other cloud service questions and receive answers from other members of the community.
...