Pipe multiple read streams to single write stream?

1,260 views
Skip to first unread message

Jan Van Ryswyck

unread,
Oct 26, 2013, 5:23:24 PM10/26/13
to nod...@googlegroups.com
Hi all,

I am playing around with streams V2 and I was wondering whether it is possible to get the following example working somehow:

//
// Reading stuff
//

var ReadingStuff = function() {
this._data = [1, 2, 3, 4, 5];

stream.Readable.call(this);
};

util.inherits(ReadingStuff, stream.Readable);

ReadingStuff.prototype._read = function() {
if(0 === this._data.length) {
this.push(null);
return;
}

this.push(this._data[0].toString());
this._data.shift();
};


//
// Writing stuff
//

var WritingStuff = function() {
stream.Writable.call(this);

this.on('finish', function() {
console.log('Finished writing stuff!!');
});
};

util.inherits(WritingStuff, stream.Writable);

WritingStuff.prototype._write = function(chunk, encoding, next) {
console.log(chunk.toString(encoding));
next();
};

//
// Application
//

var readingStuff = new ReadingStuff();
var writingStuff = new WritingStuff();

readingStuff.pipe(writingStuff);

process.nextTick(function() {
var readingStuff2 = new ReadingStuff();
readingStuff2.pipe(writingStuff);
});


I have two different read streams that I want to pipe to a single write stream on separate iterations of the event loop (suppose I implement the write stream as a singleton in my application). What I see is that the output of the first read stream is written to the write stream and when it is done, the 'finish' event is called. The output of the second stream is completely ignored. 

Is there a way to write the output of the second read stream to the write stream?  

Jonathan Ong

unread,
Oct 26, 2013, 6:43:33 PM10/26/13
to nod...@googlegroups.com
the read stream #1 will end the write stream when it is done. you don't want want that to happen. you'll want to `writingStuff.end()` yourself (not specifically this case, but in general, since the read stream #1 could take longer than #2):

reader1.pipe(writer, {end: false})

process.nextTick(function () {
  reader2.pipe(writer, {end: false})
  
  reader2.once('end', function () {
    writer.end()
  })
})

Jonathan Ong

unread,
Oct 26, 2013, 6:46:35 PM10/26/13
to nod...@googlegroups.com
crap. that is terrible. don't use next tick. i wish i could edit the post. do this:

reader1.once('end', function () {
  reader2.pipe(writer)
})
reader1.pipe(writer, {end: false})

the difference is that the read streams will pipe consecutively. if you want them to pipe concurrently, you'll have to do do `writer.end()` after all the readers emit an `end` event. in other words, you would have to do control flow.

Jan Van Ryswyck

unread,
Oct 27, 2013, 3:50:44 AM10/27/13
to nod...@googlegroups.com
That's exactly what I was looking for. I'm using the process.nextthick() here in order to simulate/illustrate that the second read stream is piping it's data much later than the first one.

Thanks.

Floby

unread,
Oct 28, 2013, 5:41:17 AM10/28/13
to nod...@googlegroups.com
It seems to me that's what stream-stream [1] does =), I know the author, he's a cool dude.

Brian Lalor

unread,
Oct 28, 2013, 6:12:11 AM10/28/13
to nod...@googlegroups.com
On Oct 28, 2013, at 5:41 AM, Floby <floren...@gmail.com> wrote:

It seems to me that's what stream-stream [1] does =), I know the author, he's a cool dude.

This is great, Floby.  I think stream-stream will be able to really simplify some fairly gnarly code I just wrote!

--
Brian Lalor

Reply all
Reply to author
Forward
0 new messages