简体   繁体   English

从另一个 lambda 异步调用 aws lambda

[英]invoke aws lambda from another lambda asynchronously

I need to invoke aws lambda from another lambda asynchronously.我需要从另一个 lambda 异步调用 aws lambda。 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.但就我而言,'testLambda' 是一个耗时的函数。 Because i need to exit just after invoking the 'testLambda' function.因为我需要在调用“testLambda”函数后立即退出。 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).但是我的“testLambda”函数没有被调用(没有为测试 lambda 生成云监视日志)。 what is the issue related with this code.与此代码相关的问题是什么。

Per the Lambda invoke() documentation , you will see that by default the Lambda function is invoked using the RequestResponse invocation type.根据Lambda invoke() 文档,您将看到默认情况下使用RequestResponse调用类型调用 Lambda 函数。 To invoke the function asynchronously you need to specify the Event invocation type, like so:要异步调用该函数,您需要指定Event调用类型,如下所示:

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

I was working with the currently latest node.js 8.10 version in AWS Lambda.我正在 AWS Lambda 中使用当前最新的node.js 8.10版本。
The second lambda didn't execute (and the callback function was never called) until i used the async/await mechanism.在我使用async/await机制之前,第二个 lambda 没有执行(并且从未调用回调函数)。
So the handler function must be async, and the 'lambda.invoke' call be wrapped with a Promise .所以处理函数必须是异步的,并且 'lambda.invoke' 调用用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.请注意,处理程序不会等待第二个 lambda 退出,只会等待它被触发并调用回调函数。

You could also return the Promise from within the handler, don't have to use await with a second function.您还可以从处理程序中返回Promise ,不必将await与第二个函数一起使用。

No need for any import when working with Promises and async/await, other than:使用 Promises 和 async/await 时不需要任何导入,除了:

const AWS = require('aws-sdk');
const lambda = new AWS.Lambda();

With reference to Ronginat's answer , instead of wrapping lambda.invoke() in a Promise, you could directly use lambda.invoke().promise() and do something like this: (tested in Node.js 12.x)参考Ronginat 的回答,您可以直接使用lambda.invoke().promise()并执行以下操作,而不是将lambda.invoke()包装在 Promise 中:(在 Node.js 12.x 中测试)

exports.handler = async (event) => {

    const payload = 'hello from lambda 1';

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

    const LambdaPromise = (params) => lambda.invoke(params).promise();

    const responseFromLambda2 = await LambdaPromise(params);

    return responseFromLambda2; //this should return {StatusCode: 202, Payload: ''}
};

That's how I use in Express.js这就是我在 Express.js 中的使用方式


var express = require("express");
var router = express.Router();

const asyncMiddleware = fn =>
  (req, res, next) => {
    Promise.resolve(fn(req, res, next))
      .catch(next);
  };

const invokeLambda = async (params) => {
  const data = await lambda.invoke(params).promise();
  return JSON.parse(data.Payload);
}


router.get('/test', asyncMiddleware(async (req, res, next) => {
  const params = {
    FunctionName: SOMETHING_LAMBDA_ARN,
    Payload: JSON.stringify(req.body)
  };
  const result = await invokeLambda(params);
  res.send(result);
}));

I wanted a similar solution as above.我想要一个与上面类似的解决方案。 Though step functions are now recommended when using multiple lambda functions over lambda.invoke , I used the following code snippet to asynchronously call two other lambda functions from my base lambda function.虽然现在建议在lambda.invoke使用多个 lambda 函数时使用 step 函数,但我使用以下代码片段从我的基本 lambda 函数异步调用另外两个 lambda 函数。

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

exports.handler = async(event) => {
   await invokeLambda(event);
   
   const response = {
        statusCode: 200,
        body: JSON.stringify('success'),
   };
   
   return response;
};

//Invoke Multiple Lambda functions
  async function invokeLambda(event) {
    const function1 = {
        FunctionName: 'dev-test-async-lambda-1',
        InvocationType: 'Event',
        Payload: JSON.stringify(event)
    };

    const function2 = {
        FunctionName: 'dev-test-async-lambda-2',
        InvocationType: 'Event',
        Payload: JSON.stringify(event)
    };
    
    await lambda.invoke(function1).promise();
    await lambda.invoke(function2).promise();

}

        

Let me know if I can improve this.让我知道我是否可以改进这一点。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM