У меня есть корзина AWS S3 с кучей файлов журналов.У меня есть лямбда-функция, использующая node.js 8.10, которая читает каждую строку файла журнала.Вот что у меня есть:
const readline = require('readline');
exports.handler = async (event) => {
try {
let bucket = event.Records[0].s3.bucket.name;
let key = event.Records[0].s3.object.key;
// documentation for this method:
// https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/S3.html#getObject-property
let readStream = S3.getObject({ Bucket: bucket, Key: key }).createReadStream(); // 1
const rl = readline.createInterface({
input: readStream
});
rl.on('line', async (line) => {
console.log(line);
// process line as needed
});
} catch (err) {
console.log(err);
return err;
}
};
В приведенном выше фрагменте я печатаю строку в файле журнала на консоль только для тестирования, но я не вижу никакого вывода.
Но если я реорганизую код, подобный этому, он будет работать:
const stream = require('stream');
const bufferStream = new stream.PassThrough();
const readline = require('readline');
exports.handler = async (event) => {
try {
// retrieving first record only just for
// testing
let bucket = event.Records[0].s3.bucket.name;
let key = event.Records[0].s3.object.key;
// data.Body is a Buffer
let data = await S3.getObject({ Bucket: bucket, Key: key }).promise();
bufferStream.end(data.Body); // 2
const rl = readline.createInterface({
input: bufferStream
});
rl.on('line', (line) => {
console.log(line);
// process line as needed
});
} catch (err) {
console.log(err);
return err;
}
};
Для строки, отмеченной 2, функция getObject возвращает буфер и преобразуется в поток.
Возможно лисделать это без использования буфера?Я думаю, что если файл журнала очень большой, конвертировать буфер в поток неэффективно.Мне интересно, могу ли я использовать поток напрямую, как в строке, помеченной 1.
РЕДАКТИРОВАТЬ: я провел еще несколько испытаний и заставил его работать, но без асинхронной лямбда-функции.Вот оно:
exports.handler = function (event, context, callback) {
// for testing I'm looking at the first record
let bucket = event.Records[0].s3.bucket.name;
let key = event.Records[0].s3.object.key;
const readStream = S3.getObject({ Bucket: bucket, Key: key }).createReadStream();
const rl = readline.createInterface({
input: readStream,
crlfDelay: Infinity
});
rl.on('line', (line) => {
console.log(line);
});
}
Кто-нибудь знает, почему этот переработанный код работает, но не с асинхронной лямбдой?