Непоследовательные результаты при вызове API от AWS Lambda - PullRequest
0 голосов
/ 25 октября 2018

Позвольте мне заранее извиниться за этот ужасный код.У меня практически нет опыта работы с узлами, и я пишу все свои JS с приложениями React и Elixir на серверной части.Я изо всех сил пытаюсь написать правильную лямбда-функцию в NodeJS, и я в основном что-то совместил с Googling / SO / методом проб и ошибок и т. Д.

Я делаю следующее:

  • Пользователь хочет загрузить файл, чтобы он отправил некоторую информацию в серверную часть.
  • Серверная часть создает предварительно назначенный ключ.
  • Пользовательская часть отправляет файл в S3.
  • S3 запускает событие, и Lambda выполняет
  • Lambda теперь проверяет mimetype и, если это плохой файл, удалит файл из корзины S3 и сделает вызов API DELETE в мой бэкэнд, чтобы сообщить ему об удалении строки фотографииЗагрузка принадлежит.

Когда я пытаюсь выполнить API-вызов к своему внутреннему интерфейсу внутри вызова s3.deleteObject, я получаю крайне противоречивые результаты.Много времени он отправляет два запроса на удаление в одном и том же исполнении Lambda.Иногда кажется, что он никогда даже не вызывает бэкэнд, а просто запускается и показывает завершенный, не регистрируя ничего в Cloudwatch.

Мой код выглядит следующим образом:

    const aws = require('aws-sdk');

    const s3 = new aws.S3({apiVersion: '2006-03-01'});

    const fileType = require('file-type');

    const imageTypes = ['image/gif', 'image/jpeg', 'image/png'];

    const request = require('request-promise');

    exports.handler = async (event, context) => {
      // Get the object from the event and show its content type
      const bucket = event.Records[0].s3.bucket.name;
      const key = decodeURIComponent(
        event.Records[0].s3.object.key.replace(/\+/g, ' ')
      );

      const params = {
        Bucket: bucket,
        Key: key,
      };

      try {
        const {Body} = await s3.getObject(params).promise();

        const fileBuffer = new Buffer(Body, 'base64');
        const fileTypeInfo = fileType(fileBuffer);

        if (
          typeof fileTypeInfo !== 'undefined' &&
          fileTypeInfo &&
          imageTypes.includes(fileTypeInfo.mime)
        ) {
          console.log('FILE IS OKAY.');
        } else {
          await s3
            .deleteObject(params, function(err, data) {
              console.log('FILE IS NOT AN IMAGE.');
              if (err) {
                console.log('FAILED TO DELETE.');
              } else {
                console.log('DELETED ON S3.  ATTEMPTING TO DELETE ON SERVER.');

                const url =
                  `http://MYSERVERHERE:4000/api/event/${params.Key.split('.')[0]}`;

                const options = {
                  method: 'DELETE',
                  uri: url,
                };

                request(options)
                  .then(function(response) {
                    console.log('RESPONSE: ', response);
                  })
                  .catch(function(err) {
                    console.log('ERROR: ', err);
                  });
              }
            })
            .promise();
        }
        return Body;
      } catch (err) {
        const message = `Error getting object ${key} from bucket ${bucket}. Make sure they exist and your bucket is in the same region as this function.`;
        console.log(message);
        throw new Error(message);
      }
    };

Это сводит меня с ума из-задней.Любая помощь приветствуется, чтобы объяснить, почему я получаю неожиданные результаты от лямбда-функции, подобной этой.

Ответы [ 2 ]

0 голосов
/ 25 октября 2018

Операция удаления S3 в конечном итоге согласована во всех регионах.

Следовательно, в соответствии с параметром AWS (захваченная релевантная информация),

  • Процесс удаляет существующий объект и сразу пытается прочитать его,Пока удаление не будет полностью распространено, Amazon S3 может возвращать удаленные данные.
  • Процесс удаляет существующий объект и сразу же перечисляет ключи в своем сегменте.Пока удаление не будет полностью распространено, Amazon S3 может перечислить удаленный объект.

Ссылка: https://docs.aws.amazon.com/AmazonS3/latest/dev/Introduction.html#ConsistencyModel

0 голосов
/ 25 октября 2018

Пожалуйста, проверьте после обновления вашу else деталь с правильным await use

Пожалуйста, попробуйте ниже код.

exports.handler = async (event, context) => {
  // Get the object from the event and show its content type
  const bucket = event.Records[0].s3.bucket.name;
  const key = decodeURIComponent(
    event.Records[0].s3.object.key.replace(/\+/g, ' ')
  );

  const params = {
    Bucket: bucket,
    Key: key,
  };

  try {
    const {Body} = await s3.getObject(params).promise();

    const fileBuffer = new Buffer(Body, 'base64');
    const fileTypeInfo = fileType(fileBuffer);

    if (
      typeof fileTypeInfo !== 'undefined' &&
      fileTypeInfo &&
      imageTypes.includes(fileTypeInfo.mime)
    ) {
      console.log('FILE IS OKAY.');
    } else {
      await s3.deleteObject(params).promise(); //fail then catch block execute
        console.log('DELETED ON S3.  ATTEMPTING TO DELETE ON SERVER.');

        const url =
          `http://MYSERVERHERE:4000/api/event/${params.Key.split('.')[0]}`;

        const options = {
          method: 'DELETE',
          uri: url,
        };

        let response = await request(options); ////fail then catch block execute
        console.log(response);
      }
    return Body;
  } catch (err) {
    console.log(err);
    const message = `Error getting object ${key} from bucket ${bucket}. Make sure they exist and your bucket is in the same region as this function.`;
    console.log(message);
    throw new Error(message);
  }
};
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...