【发布时间】:2021-09-19 04:35:15
【问题描述】:
我不知道这是否与父 Lambda 是 node.js 运行时而子 Lambda 是 Python 3.8 的事实有关,但是我遇到了一些奇怪的行为,我不知道出了什么问题...
tldr:子 lambda 仅在父 lambda“睡眠”(调用 setTimeout())100 毫秒或更长时间时才被调用。
我有两个简单的 AWS Lambda 函数。一种是用 JS(node.js 运行时)编写的,另一种是用 Python(3.8)编写的。设置很简单。父 node.js 函数调用子 python 函数。调用是异步的,父进程不必等待子进程返回。父节点必须是node.js,子节点必须是python 3.8。
我的观察是,除非父 lambda“睡眠”至少 100 毫秒,否则不会调用子 python lambda。我知道这听起来很奇怪,但我不确定我做错了什么并且花了几天时间试图解决这个问题(毫无疑问它真的很简单......)。
我编写了一个“睡眠”函数(显示在 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 ms,则不会调用子 lambda。异步或同步调用子函数(通过将父函数中的params 中的"Event" 替换为"RequestResponse" 不会改变任何内容,以上仍然成立。
这种奇怪行为的原因是什么?我做错了什么?
编辑 @jellycsc 链接到调用调用命令的替代方法:
var invoke = lambda.invoke(params).promise()
invoke.then(function(data) {
console.log('Success');
}).catch(function(err) {
console.log(err);
});
很遗憾,这并不能解决问题,而且只有在定时器设置为 100 毫秒或更长的情况下才会调用调用命令。
【问题讨论】:
-
嘿@jellycsc 感谢您的评论。您链接到的文档仅提供了执行调用命令的替代方法,它不能解决问题。我更新了我的问题,向您展示我是如何修改呼叫的。如果我遗漏了什么,请告诉我!
-
您需要返回一个承诺以避免 lambda 在所有任务完成之前终止。 docs.aws.amazon.com/lambda/latest/dg/nodejs-handler.html
-
知道了,非常感谢您的帮助!
标签: javascript python node.js amazon-web-services aws-lambda