FTP в AWS Lambda - проблемы с загрузкой файлов (Async / Await) - PullRequest
0 голосов
/ 02 марта 2019

Я боролся с различными модулями FTP-узлов, чтобы попытаться заставить что-либо работать в AWS Lambda.Лучшим и самым популярным кажется «Basic-FTP», который также поддерживает async / await.Но я просто не могу заставить его загружать файлы, когда какой-либо код добавляется ниже функции FTP.

Я не хочу добавлять функции fs в асинхронную функцию FTP, так как мне нужно решить, что вызывает разрывкогда любой код ниже добавлен, и у меня также есть другие биты кода для добавления и работы с загруженным файлом и его содержимым позже:

FTP SUCCESS - Когда асинхронная функция используется только снет кода fs под ним

FTP FAILURE - Добавление функций fs readdir / readFile или любого другого кода ниже

ERROR Error: ENOENT: no such file or directory, open '/tmp/document.txt'

https://github.com/patrickjuchli/basic-ftp

const ftp = require("basic-ftp");
const fs = require("fs");
var FileNameWithExtension = "document.txt";
var ftpTXT;

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

    example();

    async function example() {
        const client = new ftp.Client();
        //client.ftp.verbose = true;
        try {
            await client.access({
                host: host,
                user: user,
                password: password,
                //secure: true
            });
            console.log(await client.list());
            await client.download(fs.createWriteStream('/tmp/' + FileNameWithExtension), FileNameWithExtension);
        }
        catch (err) {
            console.log(err);
        }
        client.close();
    }

    // Read the content from the /tmp/ directory to check FTP was succesful
    fs.readdir("/tmp/", function (err, data) {
        if (err) {
            return console.error("There was an error listing the /tmp/ contents.");
        }
        console.log('Contents of AWS Lambda /tmp/ directory: ', data);
    });

    // Read TXT file and convert into string format
    fs.readFile('/tmp/' + FileNameWithExtension, 'utf8', function (err, data) {
        if (err) throw err;
        ftpTXT = data;
        console.log(ftpTXT);
    });

    // Do other Node.js coding with the downloaded txt file and it's contents
};

1 Ответ

0 голосов
/ 02 марта 2019

Проблема в том, что вы теряетесь при создании асинхронной функции внутри вашего обработчика.Поскольку example() является асинхронным, возвращается Обещание.Но вы не await на нем, так что, как это было закодировано, это что-то вроде пожара и забыть.Кроме того, ваша лямбда завершается до того, как срабатывают ваши обратные вызовы, поэтому даже если она загрузится, вы не сможете ее увидеть.

Я предлагаю вам обернуть ваши обратные вызовы в Promises, чтобы вы могли легко awaitна них из вашей функции-обработчика.

Мне удалось заставить его работать: я использовал https://dlptest.com/ftp-test/ для тестирования, поэтому измените его соответствующим образом.Кроме того, убедитесь, что я загрузил файл сам.Так что если вы хотите повторить этот пример, просто создайте файл readme.txt в корневом каталоге вашего проекта и загрузите его.Если у вас уже есть этот файл readme.txt на вашем FTP-сервере, просто удалите строку, в которую он загружает файл.

Вот рабочий пример:

const ftp = require("basic-ftp");
const fs = require("fs");
const FileNameWithExtension = "readme.txt";

module.exports.hello = async (event) => {

  const client = new ftp.Client();
  try {
    await client.access({
      host: 'ftp.dlptest.com',
      user: 'dlpuser@dlptest.com',
      password: 'puTeT3Yei1IJ4UYT7q0r'
    });
    console.log(await client.list());
    await client.upload(fs.createReadStream(FileNameWithExtension), FileNameWithExtension)
    await client.download(fs.createWriteStream('/tmp/' + FileNameWithExtension), FileNameWithExtension);
  }
  catch (err) {
    console.log('logging err')
    console.log(err);
  }
  client.close();

  console.log(await readdir('/tmp/'))

  console.log(await readfile('/tmp/', FileNameWithExtension))

  return {
    statusCode: 200,
    body: JSON.stringify({message: 'File downloaded successfully'})
  }

};

const readdir = dir => {
  return new Promise((res, rej) => {
    fs.readdir(dir, function (err, data) {
      if (err) {
        return rej(err);
      }
      return res(data)
    });
  })
}

const readfile = (dir, filename) => {
  return new Promise((res, rej) => {
    fs.readFile(dir + filename, 'utf8', function (err, data) {
      if (err) {
        return rej(err);
      }
      return res(data)
    })
  })
}

Вот выходные данныеЛямбда-функция:

enter image description here

А вот полные журналы CloudWatch:

enter image description here

Мой файл содержит только привет.Вы можете увидеть это в журналах.

Имейте в виду, что в лямбда-функциях у вас есть ограничение в 512 МБ при загрузке чего-либо в / tmp.Вы можете увидеть ограничения в документах

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...