在执行主要步骤之前,先在Lambda中加载S3文件 [英] Load S3 file in lambda before main procedure

查看:131
本文介绍了在执行主要步骤之前,先在Lambda中加载S3文件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在编写一个lambda函数,该函数需要加载存储在S3中的密钥.它不会经常更改,因此我不想每次调用lambda函数时都抓取它,因此我想在容器启动时将其加载一次,然后在lambda容器的生命周期内保留该值.

I am writing a lambda function that needs to load a key that is being stored in S3. It wont change often so I'd rather not grab it every time the lambda function is called, so I would like to load it once when the container is spun up and then keep that value for the lifetime of the lambda container.

但是,由于异步方法getObject,这会导致问题,因为在运行主模块时可能未加载文件.导出代码被运行(特别是如果这是第一次运行并且正在创建容器)

However, due to the asynchronous method getObject this is causing an issue as the file may not have been loaded when the main module.export code gets run (particularly if this is the first run for a while and container is being created).

我已经使用setTimeout实现了一种解决方法,但是我想看看推荐的方法是什么,并且我的方法是否有问题,因为感觉不正确!

I've implemented a workaround using setTimeout but I wanted to see what the recommended way aorund this was, and are there any issues with my approach as it just doesn't feel right!

示例代码:

var AWS = require('aws-sdk')
var s3 = new AWS.S3();

var fileLoaded = false;

var params = {
  Bucket: 'bucket-name',
  Key: 'file-name'
};

s3.getObject(params, function(err, data) {
  if (err) console.log(err, err.stack); // an error occurred
  else {
      console.log('File loaded from S3');
      fileLoaded = true;
  }
});

exports.handler = (event, context, callback) => {

    console.log('I am in the main procedure, but i might not have the file yet')
    waitForFileLoadBeforeDoingSomething(event, context, callback)

};

function waitForFileLoadBeforeDoingSomething(event, context, callback){
    if(!fileLoaded){
        console.log('No file available to me yet, we will sleep')
        setTimeout(function(){
            waitForFileLoadBeforeDoingSomething(event, context, callback)
        }, 300)
    } else {
        console.log('I have the file!')
        doStuff(event, context, callback)
    }
}

function doStuff(event, context, callback){
    console.log('Now I can do the rest of the code')
    //Do the actual code here

    callback(null, 'success')
}

推荐答案

跟随pspi的答案和更多研究,我认为更正确的解决方案是:

Following pspi's answer and some more research I think a more correct solution would be this:

var AWS = require('aws-sdk')
var s3 = new AWS.S3();

var params = {
    Bucket: 'bucket-name',
    Key: 'file-name'
};

var fileLoaded = false;

exports.handler = (event, context, callback) => {

    if(!fileLoaded){
        s3.getObject(params, function (err, data) {
            if (err) console.log(err, err.stack);
            else {
                fileLoaded = true;
                doSomething(event, context, callback)
            }
        });
    } else {
        doSomething(event, context, callback)
    }

};

function doSomething(event, context, callback){

    //Do the actual work here

    callback(null, "success") //Then end
}

这似乎提供了仅从S3加载一次文件但没有完成加载就不允许代码执行的预期结果.如果它多次被冷调用,将允许多次向S3发出请求,但这是不可能的,并且仍然比每次调用该函数都要好.

This seems to give the desired outcome of only loading the file from S3 once but not allowing code execution without the load having finished. It would allow multiple requests to S3 if it was called cold multiple times quickly but that's unlikely and still better than every time the function is called.

这篇关于在执行主要步骤之前,先在Lambda中加载S3文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆