使用 AWS Lambda 中的 AWS S3 服务调用正确处理 context.succeed()/context.fail()
Properly handling context.succeed()/context.fail() with AWS S3 service calls in AWS Lambda
我已经搜索过此处(即 How do you structure sequential AWS service calls within lambda given all the calls are asynchronous?)和其他地方的帖子,但似乎找不到一点点信息来帮助我解决这个恼人的问题。
当您有一个循环遍历的 Lambda 函数,并在该循环中调用 s3.putObject() 时,它会在尝试正确处理 context.succeed() 时遇到短路问题/context.fail() 或关闭 Lambda 进程的旧 context.done(null, 'msg') 方式。
即迭代需要使用要上传的当前对象调用 s3.putObject(),但仍会输出到 cloudwatch 或可能 SQS/SNS 成功 上传的文件。但是,我将这种类型的闭包放入函数中的所有尝试都会遇到随机结果,有时会获取文件名,有时只会获取一些文件名等。
最好的方法是什么?我尝试过使用 Q 和异步,但老实说,我仍在学习所有这些东西..
下面是我正在尝试做的粗略示例:
function output(s3Object){
s3.putObject(s3Object, function(err, data){
if (err) {
console.log('There was an issue with outputting the object.', err);
} else {
// how do you properly close this if you have x number of incoming calls??
// context.done(null, 'success');
}
// and later in the code where it actually calls the output function
// and NOTE: it should output all of the file names that the invocation uploads!
for (var a = 0; a < myRecords.length; a++){
output(myRecords[a]);
}
但是,正如我之前所说,到目前为止我所做的任何尝试都得到了不同的结果。
Successfully output object: myBucket/prefix/part_000000123432345.dat
Successfully output object: myBucket/prefix/part_000000123432346.dat
但是函数的另一个测试输出:
Successfully output object: myBucket/prefix/part_000000123432346.dat
哎呀
我将给出一个使用 Async 的简单示例,然后您可以对其进行调整:
var async = require('async');
var sleep = function(message, callback) {
setTimeout(function() {
callback(null, "Echo: " + message);
}, Math.floor(Math.random() * 2000));
};
exports.handler = function(event, context) {
async.map(['a', 'b', 'c', 'd', 'e'], sleep, context.done);
};
我在这里定义了一个 sleep()
函数,它接受消息和回调,然后休眠 0 到 2 秒之间的随机时间,然后将消息回显给回调。
然后我们使用 async.map()
对 5 条不同的消息异步调用 sleep()
函数。根据 the docs,此函数的回调(在本例中为 context.done
)将在 所有迭代器函数完成时调用 。 运行 这在 Lambda 控制台中,果然,你得到:
[
"Echo: a",
"Echo: b",
"Echo: c",
"Echo: d",
"Echo: e"
]
因此您的代码可能很简单:
async.map(myRecords, s3.putObject, context.done);
但由于我无法测试,所以我会把那部分留给你。
我已经搜索过此处(即 How do you structure sequential AWS service calls within lambda given all the calls are asynchronous?)和其他地方的帖子,但似乎找不到一点点信息来帮助我解决这个恼人的问题。 当您有一个循环遍历的 Lambda 函数,并在该循环中调用 s3.putObject() 时,它会在尝试正确处理 context.succeed() 时遇到短路问题/context.fail() 或关闭 Lambda 进程的旧 context.done(null, 'msg') 方式。
即迭代需要使用要上传的当前对象调用 s3.putObject(),但仍会输出到 cloudwatch 或可能 SQS/SNS 成功 上传的文件。但是,我将这种类型的闭包放入函数中的所有尝试都会遇到随机结果,有时会获取文件名,有时只会获取一些文件名等。
最好的方法是什么?我尝试过使用 Q 和异步,但老实说,我仍在学习所有这些东西..
下面是我正在尝试做的粗略示例:
function output(s3Object){
s3.putObject(s3Object, function(err, data){
if (err) {
console.log('There was an issue with outputting the object.', err);
} else {
// how do you properly close this if you have x number of incoming calls??
// context.done(null, 'success');
}
// and later in the code where it actually calls the output function
// and NOTE: it should output all of the file names that the invocation uploads!
for (var a = 0; a < myRecords.length; a++){
output(myRecords[a]);
}
但是,正如我之前所说,到目前为止我所做的任何尝试都得到了不同的结果。
Successfully output object: myBucket/prefix/part_000000123432345.dat
Successfully output object: myBucket/prefix/part_000000123432346.dat
但是函数的另一个测试输出:
Successfully output object: myBucket/prefix/part_000000123432346.dat
哎呀
我将给出一个使用 Async 的简单示例,然后您可以对其进行调整:
var async = require('async');
var sleep = function(message, callback) {
setTimeout(function() {
callback(null, "Echo: " + message);
}, Math.floor(Math.random() * 2000));
};
exports.handler = function(event, context) {
async.map(['a', 'b', 'c', 'd', 'e'], sleep, context.done);
};
我在这里定义了一个 sleep()
函数,它接受消息和回调,然后休眠 0 到 2 秒之间的随机时间,然后将消息回显给回调。
然后我们使用 async.map()
对 5 条不同的消息异步调用 sleep()
函数。根据 the docs,此函数的回调(在本例中为 context.done
)将在 所有迭代器函数完成时调用 。 运行 这在 Lambda 控制台中,果然,你得到:
[
"Echo: a",
"Echo: b",
"Echo: c",
"Echo: d",
"Echo: e"
]
因此您的代码可能很简单:
async.map(myRecords, s3.putObject, context.done);
但由于我无法测试,所以我会把那部分留给你。