AWS лямбда никогда не завершается, но также не отображается время ожидания - PullRequest
0 голосов
/ 17 февраля 2020

Я пытаюсь создать простое приложение. Пользователь отправляет вложение в специальный почтовый ящик, AWS SES получает письмо и сохраняет его в S3, запускается лямбда-функция, и лямбда находит письмо в S3, анализирует вложение (в данном случае jpg), а затем хранит его в другом ведре S3. Наконец, приложение создает в Airtable новую строку с изображением в виде вложения.

Когда я вызывал эту функцию локально, используя сервер, все работает нормально. Письмо с изображением уже хранится в корзине S3, поэтому я создал макет, который явно передает ключ моей лямбде. Однако, когда я развертываю приложение и отправляю тестовое электронное письмо, происходит следующее:

  • Электронная почта хранится в корзине S3 'to-airtable-temp'
  • Вызывается лямбда-функция

До того, как электронная почта будет найдена и вложение отброшено и сохранено в отдельном контейнере S3, функция просто останавливается. Нет сообщения об ошибке или тайм-аут. Это просто останавливается. Журналы Cloudwatch выглядят следующим образом:

START RequestId: 6a0364ae-0879-4ee1-9dcd-c8747de1a650 Version: $LATEST
2020-02-17T07:39:55.465Z    6a0364ae-0879-4ee1-9dcd-c8747de1a650    INFO    {
  s3SchemaVersion: '1.0',
  configurationId: 'emailtoairtable-dev-parse-224c3963d3a3f9c35018ae93a9fffea4',
  bucket: {
    name: 'to-airtable-temp',
    ownerIdentity: { principalId: 'AI5RGHFD5AFHE' },
    arn: 'arn:aws:s3:::to-airtable-temp'
  },
  object: {
    key: 'mtvuuiokqj55l2a8b0qser7tn9dhfignoh9c1vg1',
    size: 3804230,
    eTag: 'c821fb0a2a9c3b060e20e7d177f8b972',
    sequencer: '005E4A434810147365'
  }
}
2020-02-17T07:39:55.465Z    6a0364ae-0879-4ee1-9dcd-c8747de1a650    INFO    key mtvuuiokqj55l2a8b0qser7tn9dhfignoh9c1vg1
2020-02-17T07:39:55.465Z    6a0364ae-0879-4ee1-9dcd-c8747de1a650    INFO    Key pushed to list.  mtvuuiokqj55l2a8b0qser7tn9dhfignoh9c1vg1
END RequestId: 6a0364ae-0879-4ee1-9dcd-c8747de1a650
REPORT RequestId: 6a0364ae-0879-4ee1-9dcd-c8747de1a650  Duration: 1113.17 ms    Billed Duration: 1200 ms    Memory Size: 1024 MB    Max Memory Used: 114 MB Init Duration: 119.56 ms

Вот мой обработчик. js file:

'use strict';

module.exports.parse = async event => {
  try {
    const aws = require('aws-sdk');
    const s3 = new aws.S3();
    const simpleParser = require('mailparser').simpleParser;
    const Airtable = require('airtable');
    const dateformat = require('dateformat');
    var base = new Airtable({ apiKey: process.env.airtableApiKey}).base(process.env.airtableBaseId);
    var data = [];
    var keys = [];

    event["Records"].forEach(async record => {
      console.log(record["s3"]);
      console.log('key', record["s3"]["object"]["key"]);
      keys.push(record["s3"]["object"]["key"]);
      console.log('Key pushed to list. ', record["s3"]["object"]["key"]);  // <-- this is the last line that I am sure processes because I see it in the CloudWatch logs.
      var temp_data = await s3.getObject(
      {
        Bucket: 'to-airtable-temp', 
        Key: record["s3"]["object"]["key"]
      }).promise();
      console.log('temp_data', temp_data);
      data.push(temp_data);
    });

    setTimeout( async function() {
      // console.log('data', data[0].Body.toString());
      let parsed = await simpleParser(data[0].Body.toString());
      console.log(parsed);
      // save the file to a public S3 bucket so it can be uploaded to airtable
      parsed["attachments"].forEach(function(attachment) {
        let now = new Date();
        s3.upload({
          Bucket: 'to-airtable-images',
          Key: keys[0] + dateformat(now, "yyyy-mm-dd") + '.jpg',
          Body: attachment.content,
          ContentType: "image/jpeg"
        },
        function(error, data) {
          if (error) {
            throw error;
          }
          console.log('File uploaded successfully. ' +data.Location);
          // Now upload to airtable
          base('Input').create([
            {
              "fields": {"Attachments": [
                {
                  "url": data.Location
                }
              ]}
            }
          ], function(err, records) {
            if (err) {
              console.error(err);
              return;
            }
            records.forEach(function (record) {
              console.log(record.getId());
            });
          });
        });
      });

      return {
        statusCode: 200,
        body: JSON.stringify(
          {
            message: 'Go Serverless v1.0! Your function executed successfully!',
            input: event,
            data: JSON.stringify(data),
          },
          null,
          2
        ),
      };
    }, 500);  // I've tried increasing this time but it still hangs.
  } catch (error) {
    console.error(error);
  }
};

1 Ответ

1 голос
/ 17 февраля 2020

Вы не должны использовать async/await с функцией forEach. Использование async / await с forEach l oop. Вместо этого используйте более современный синтаксис for of:

for (let record of event["Records"]) {
   // you can include await calls in this block
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...