【问题标题】:Properly handling context.succeed()/context.fail() with AWS S3 service calls in AWS Lambda在 AWS Lambda 中使用 AWS S3 服务调用正确处理 context.succeed()/context.fail()
【发布时间】:2015-07-07 23:41:38
【问题描述】:

我已经搜索过这里(即How do you structure sequential AWS service calls within lambda given all the calls are asynchronous?)和其他地方的帖子,但似乎找不到一点点信息可以帮助我解决这个烦人的问题。 当您有一个遍历循环的 Lambda 函数,并且在该循环中调用 s3.putObject() 时,它会在尝试正确处理 context.succeed()/context.fail 时遇到短路问题() 或旧的 context.done(null, 'msg') 关闭 Lambda 进程的方式。

I.E.迭代需要使用要上传的当前对象调用 s3.putObject(),但仍将成功上传的文件输出到 cloudwatch 或 SQS/SNS。但是,我将这种类型的闭包放入函数中的所有尝试都会遇到随机结果,有时会获取文件名,有时只获取一些文件名,等等。

最好的方法是什么?我尝试使用 Q 和 async,但老实说,我仍在学习所有这些东西..

以下是我正在尝试做的一个粗略示例:

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

啊。

【问题讨论】:

    标签: node.js asynchronous amazon-web-services amazon-s3 aws-lambda


    【解决方案1】:

    我将给出一个使用 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);
    

    但由于我无法对此进行测试,所以我将把这部分留给你。

    【讨论】:

    • 我想知道这种方法的一件事是,如果数组参数中的这些项目之一导致函数失败会发生什么?是否会在出现错误时完全停止处理?
    • 是的。如果这不是您想要的,您可以捕获错误并返回一个布尔值来表示成功/失败。然后在回调中你会知道哪些puts成功了,因为数组的顺序是一样的。
    猜你喜欢
    • 2020-05-14
    • 2017-07-28
    • 2018-03-10
    • 1970-01-01
    • 2017-01-10
    • 1970-01-01
    • 1970-01-01
    • 2018-07-12
    • 2017-09-22
    相关资源
    最近更新 更多