Как клонировать читаемый поток

У меня есть поток, который я пытаюсь отправить в два разных места назначения. Первый пункт назначения - AWS S3, второй пункт назначения - какой-то другой сервер через HTTP-запрос.

const document = fs.createReadStream(process.cwd() + "/test/resources/" + "id/document.jpg");

const s3Response = await submitToS3(document);

const backendResponse = await submitToBackend(document);

Насколько я понимаю, поток можно прочитать только один раз. Как я могу отправить один и тот же поток в два разных места назначения.

Я думал о клонировании потока, но просто создать новую переменную и назначить поток этой переменной не работает.


person Kay    schedule 24.02.2020    source источник


Ответы (2)


Ответ Рагхавендры предлагает хорошее потенциальное направление. Вы можете объединить несколько каналов из этого ответа с реализацией канала S3 из этот ответ.

Что касается части submitToBackend, я не уверен, как именно выглядит ваша реализация, но предполагая, что вы можете передать какой-либо HTTP-запрос ...

Пример:

var fs = require("fs");
const request = require("request");
const AWS = require("aws-sdk");
const s3 = new AWS.S3();

const rs = fs.createReadStream(process.cwd() + "/test/resources/" + "id/document.jpg");

function uploadFromStream(s3) {
  var pass = new stream.PassThrough();

  var params = {Bucket: BUCKET, Key: KEY, Body: pass};
  s3.upload(params, function(err, data) {
    console.log(err, data);
  });

  return pass;
}

rs.pipe(uploadFromStream(s3));

// Just guessing at your submitToBackend implementation:
const backendWs = request.post("http://example.com/docs");

// However it works, if you can get to a stream.Writable, you can now pipe the same stream.Readable:
rs.pipe(backendWs);
person Will Cain    schedule 24.02.2020
comment
submitToBackend - это асинхронная функция, мне нужно дождаться ответа - person Kay; 25.02.2020
comment
Я обновил свой вопрос, чтобы отразить, что функции являются обещаниями. - person Kay; 25.02.2020
comment
Ах, спасибо, понятно, но сам createReadStream не возвращает обещание, а скорее экземпляр fs.ReadStream. Может это единственная проблема? - person Will Cain; 25.02.2020
comment
Нет, у меня идет поток, createReadStream верен. Затем поток передается в s3 и http-запрос. - person Kay; 25.02.2020
comment
Я смущен. В вашем фрагменте кода есть await fs.createReadStream, но мы с вами согласны с тем, что createReadStream возвращает поток, а не обещание. Но await предназначен для обещаний (асинхронных функций). Думаю, это могло быть источником вашей проблемы. Но, возможно, я что-то упускаю. - person Will Cain; 25.02.2020
comment
Да, извините, мне не нужно ждать fs.createReadStream, я обновил это - person Kay; 25.02.2020

вы можете проверить этот модуль npm: https://www.npmjs.com/package/readable-stream-clone

npm install readable-stream-clone
const fs = require("fs");
const ReadableStreamClone = require("readable-stream-clone");
 
const readStream = fs.createReadStream('text.txt');
 
const readStream1 = new ReadableStreamClone(readStream);
const readStream2 = new ReadableStreamClone(readStream);
 
const writeStream1 = fs.createWriteStream('sample1.txt');
const writeStream2 = fs.createWriteStream('sample2.txt');
 
readStream1.pipe(writeStream1)
readStream2.pipe(writeStream2)
person levansuper    schedule 23.08.2020