【问题标题】:Async/Await Promise implementation is executing a single S3 PutObject call Twice - Why?Async/Await Promise 实现执行单个 S3 PutObject 调用两次 - 为什么?
【发布时间】:2021-05-15 09:33:53
【问题描述】:

我正在使用 node.js SDK 将对象放入 S3 存储桶。一切正常,但是在日志中我注意到每次调用我的 Lambda 时,它都会执行两次 putObject 操作,即使它只在代码中执行一次。我相信这与我如何通过异步/等待方式使用承诺有关(处理 promise.then.hell 的诗句

任何帮助将不胜感激。代码如下。

const AWS = require("aws-sdk");
AWS.config.region = "us-east-1";
if (process.env.AWS_CONSOLE_LOGGER_ENABLED === "true") {
  AWS.config.logger = console;
}
const S3 = new AWS.S3();

exports.handler = async (event, context) => {
  let returnObject = { status: true };

  try {
    /**
     *
     * Snip out code above - not relevant
     *
     */

    let s3ObjectBody = {
      numParticipants: numParticipants,
      ballDropOrder: currentBallDropOrder,
      ballDropSeconds: 0,
      allPrizesWon: allPrizesWon,
      roundHasEnded: false,
      winners: winners,
    };
    let s3Params = {
      Body: JSON.stringify(s3ObjectBody),
      Bucket: `my-bucket-${process.env.DEPLOYMENT_STAGE}`,
      Key: `public/${gameIdAndVersion}.json`,
      ContentType: "application/json; charset=utf-8",
    };
    await S3.putObject(s3Params, async function(error, data) {
      if (error) {
        const message = "S3.putObject failed for s3Params: " + s3Params + ",  exiting. error: " + error;
        errorCode = "S3_TEST_PUT_OBJECT_UPDATE_EXCEPTION";
        await notify(true, true, true, "CRIT", context.functionName, errorCode + " - " + message, { logGroupName: CWLGN, logStreamName: CWLSN, awsRequestId: ARID });
        returnObject = { status: false, errorCode: errorCode };
        return returnObject;
      } else {
        console.log("S3 putObject response data: ", data);
      }
    }).promise();

    /**
         *  First putObject executes successfully (returns 200), and I have an S3 Object version (ending w/ VnPuck)
         * 
         *  2021-02-11T15:00:41.973Z    744c8952-134b-4ded-9d1c-e2ef45ed083f    INFO    [AWS s3 200 0.088s 0 retries] putObject({ Body:
            '{"numParticipants":12,"ballDropOrder":[47],"ballDropSeconds":0,"allPrizesWon":false,"roundHasEnded":false,"winners":[]}',
            Bucket: 'my-bucket-dev',
            Key:
            'public/5c8d8e30-f0f8-4eae-a252-50afb3086f1c-2894.json',
            ContentType: 'application/json; charset=utf-8' })
        
            2021-02-11T15:00:41.973Z    744c8952-134b-4ded-9d1c-e2ef45ed083f    INFO    S3 putObject response data:  { ETag: '"6a447cd0092d51706756cd18c1c8cf6f"',
            VersionId: 'VipS0SJ_dzvqbE6BRjcxwdD4lvVnPuck' }
        
            But now it does another putObject, and returns a different version (ending w/ yFlrDkO_), so why the second put???? 

            2021-02-11T15:00:41.986Z    744c8952-134b-4ded-9d1c-e2ef45ed083f    INFO    [AWS s3 200 0.101s 0 retries] putObject({ Body:
            '{"numParticipants":12,"ballDropOrder":[47],"ballDropSeconds":0,"allPrizesWon":false,"roundHasEnded":false,"winners":[]}',
            Bucket: 'my-bucket-dev',
            Key:
            'public/5c8d8e30-f0f8-4eae-a252-50afb3086f1c-2894.json',
            ContentType: 'application/json; charset=utf-8' })
        
            2021-02-11T15:00:41.986Z    744c8952-134b-4ded-9d1c-e2ef45ed083f    INFO    S3 putObject response data:  { ETag: '"6a447cd0092d51706756cd18c1c8cf6f"',
            VersionId: 'dhfyxk2RXM8T0BycL4RYRhTeyFlrDkO_' }
        */

    /**
     *
     * Snip out code below - not relevant
     *
     */

    return returnObject;
  } catch (e) {
    /**
     *
     * Snip out code - not relevant
     *
     */
  }
};

【问题讨论】:

  • 请检查您的客户端是否触发了两次请求,或者是否编写了任何机制以在失败时重试先前的请求。
  • 不,不触发两次,这将是两个单独的 lambda 调用,因此 awsRequestId 在两个 putObject 执行中会有所不同。
  • 您是否尝试删除 .promise() 然后检查?

标签: node.js amazon-web-services amazon-s3 async-await promise


【解决方案1】:

您如何将 API Gateway 方法映射到 Lambda 函数?我注意到当使用 ANY 方法 --> Lambda 集成时,该函数将运行两次,一次用于 OPTIONS 请求,另一次用于实际的 GET / POST / 不管(如果请求不简单,例如由 XMLHttpRequest 生成)。

这将运行一次:

但如果你有这个,它会运行两次:

【讨论】:

  • 很高兴知道这个 Lambda 是通过 SDK 从另一个 Lambda 调用的,Lambda.Invoke(),API Gateway 不在图片中。您可以通过日志看到 lambda 的这个单次调用在日志中显示了两个 S3.putObject 条目,具有相同的 awsRequestId (744c8952-134b-4ded-9d1c-e2ef45ed083f ),这证明了它的相同执行/单次调用Lambda。
猜你喜欢
  • 2019-04-13
  • 1970-01-01
  • 2020-10-10
  • 2021-11-05
  • 1970-01-01
  • 2018-03-27
  • 2016-02-26
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多