使用node.js aws lambda调用python aws lambda函数

vkc1a9a2  于 2021-08-25  发布在  Java
关注(0)|答案(1)|浏览(514)

我不知道这是否与父lambda是node.js runtime,子是python 3.8这一事实有关,但我遇到了一些奇怪的行为,我无法找出哪里出了问题。。。
tldr:仅当父lambda“休眠”(调用settimeout())达100毫秒或更长时间时,才会调用子lambda。
我有两个简单的aws lambda函数。一个是用js(node.js运行时)编写的,另一个是用python(3.8)编写的。设置很简单。父node.js函数调用子python函数。调用是异步的,父级不必等待子级返回。父节点必须是node.js,子节点必须是python 3.8。
我的观察结果是,除非父lambda“睡眠”至少100毫秒,否则不会调用子python lambda。我知道这听起来很奇怪,但我不确定我做错了什么,我花了几天时间试图解决这个问题(毫无疑问,这真的很简单…)。
我编写了一个“sleep”函数(显示在node.js代码的顶部),在响应从父函数返回给调用方之前调用该函数。我知道.invoke回调中的代码将在父函数返回后调用,这只是为了调试目的。
以下是node.js父lambda:

var aws = require('aws-sdk')
var lambda = new aws.Lambda()

function sleep(ms) {
  return new Promise((resolve) => {
    setTimeout(resolve, ms);
  });
}  

exports.handler = async (event) => {
    const payload = {
        message: "Hey there",

    }
    var params = {
    FunctionName: 'ChildLambda', // the lambda function we are going to invoke
    InvocationType: 'Event', // RequestResponse is sync, Event Async
    LogType: 'Tail',
    Payload: JSON.stringify(payload)
  };
    lambda.invoke(params, function(err, data) {
        console.log("Invoked Lambda...")
        if (err) {
            console.log(err)
        } else if (data) {
            console.log('Data: ', data)
        }
        console.log("Lambda done")

    })
    // await sleep(100)
    const response = { 
        "isBase64Encoded": false,
        "statusCode": 202,
        "headers": {},
        "body": "HEY FROM LAMBDA"
    }
    return response;
};

下面是python子级lambda:

import requests
import json

def main(event, context):
    print("IN THE SECOND LAMBDA")
    response = {
        "statusCode": 200,
        "headers": {"my_header": "my_value"},
        "body": "hello from second lambda",
        "isBase64Encoded": False,
    }
    return response

如果您删除 sleep(100) 从父函数调用,则不调用子函数。我知道这一点,因为cloudwatch日志中没有显示任何内容。如果将传递给sleep()的参数设置为小于100毫秒,则不会调用子lambda。异步或同步调用子函数(通过替换 "Event" 具有 "RequestResponse" 在里面 params 在父函数没有改变任何东西的情况下,上述情况仍然成立。
这种奇怪行为的原因是什么?我做错了什么?
edit@jellycsc链接到调用invoke命令的替代方法:

var invoke  = lambda.invoke(params).promise()
    invoke.then(function(data) {
        console.log('Success');
    }).catch(function(err) {
        console.log(err);
    });

不幸的是,这并不能解决问题,只有当计时器设置为100毫秒或更长时间时,才会调用invoke命令。

jhkqcmku

jhkqcmku1#

等到 invoke 操作完成,然后完成lambda函数。

exports.handler = async (event) => {
  const payload = {
    message: "Hey there",

  }
  var params = {
    FunctionName: 'ChildLambda', // the lambda function we are going to invoke
    InvocationType: 'Event', // RequestResponse -  to get response from ChildLambda, Event - don't care the response (or error...)
    LogType: 'Tail',
    Payload: JSON.stringify(payload)
  };

  try {
    console.log("Invoked Lambda...")
    const data = await lambda.invoke(params).promise() // wait until invoke successfully
    console.log('Data: ', data) // data maybe empty - {} when InvocationType is Event
    console.log("Lambda done")

    return {
      "isBase64Encoded": false,
      "statusCode": 202,
      "headers": {},
      "body": "HEY FROM LAMBDA"
    }
  } catch (error) {
    // handle error
    console.log("Error", error);
    return {
      "isBase64Encoded": false,
      "statusCode": 500, // return error response
      "headers": {},
      "body": error.message
    }
  }
};

相关问题