在 Lambda 中从 S3 加载并执行 javascript 文件

问题描述 投票:0回答:1

S3中有一个hello.js,其中包含

function greet() {
    console.log(" From Greetings: ");
}

尝试加载此文件并执行脚本的nodeJS lambda。 访问 s3 的权限有效,脚本能够加载。但当它调用 exec 时会发生什么还不清楚。没有错误,但日志中也没有打印“From Greetings”。

const AWS = require('aws-sdk');
const s3 = new AWS.S3();
const { exec } = require('child_process');

exports.handler = async (event, context) => {
    const s3Bucket = 'monitor-state';
    const s3Key = 'hello.js';

    

    const params = { Bucket: s3Bucket, Key: s3Key };

    try {
        const data = await s3.getObject(params).promise();
        const script = data.Body.toString();

        // Execute the script
        exec(`node -e "${script}"`, (error, stdout, stderr) => {
            if (error) {
                console.error(`Script execution error: ${error}`);
                return context.fail('Error executing the script.');
            } else {
                console.log('Script execution output:');
                console.log(stdout);
                return context.succeed('Script executed successfully.');
            }
        });
    } catch (error) {
        console.error('Error fetching the script from S3:', error);
        return context.fail('Error executing the script.');
    }
};

我尝试了几种调用 exec 的方法,但似乎都不起作用。

javascript aws-lambda
1个回答
0
投票

您的 lambda 处理程序运行

exec
但不会等待子进程完成。

exec
立即返回,并且由于您的处理程序是异步的,因此处理程序会在其之后立即返回一个已完成的承诺。这足以让 Lambda 停止处理。

将你的 exec 回调变成一个承诺并等待它:

const AWS = require("aws-sdk");
const s3 = new AWS.S3();
const { exec } = require("child_process");

exports.handler = async () => {
  const s3Bucket = "monitor-state";
  const s3Key = "hello.js";

  const params = { Bucket: s3Bucket, Key: s3Key };

  const data = await s3.getObject(params).promise();
  const script = data.Body.toString();

  // Execute the script
  const [stdout, stderr] = await new Promise((resolve, reject) =>
    exec(`node -e "${script}"`, (error, stdout, stderr) => {
      if (error) {
        reject(error);
      }
      resolve([stdout, stderr]);
    }),
  );
  console.log('Script execution output:');
  console.log(stdout);
};

如果您使用 Promise,则无需使用

context
,所有被拒绝的 Promise 将被视为错误并记录到 CloudWatch。

此外,在每次 Lambda 调用时从 S3 加载代码的用例是什么?根据您的任务,最好将其放在 Lambda 层或使用 Step 函数。

© www.soinside.com 2019 - 2024. All rights reserved.