Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Multiple listeners reading from the same stream in NodeJS

Tags:

node.js

I need two different listeners to read the input coming from a readable stream. They seem to have a race condition, and I want to make sure I get this right...

When I use .on('data') - each listener gets back the same chunk and can read it.

When I use .on('readable') - the first listener to catch the event will read from the buffer, and the second listener will get an empty buffer?

Meaning I cannot use .on('readable') event when I have TWO listeners?

like image 661
Bachman Avatar asked Jun 28 '18 06:06

Bachman


1 Answers

  1. When the readable event is emitted, both the listeners listen. However, the first to call the read() function would get the data and second one would get an empty buffer because it's the same input stream being read twice and only a single chunk was present.

  2. When the data event is emitted the listener receives the chunk of data being read from the stream. So all the listeners receive the same data.

[EDIT] In detail how it works:

All readable streams begin in 2 modes: flowing and paused. All Readable streams begin in paused mode by default but they can be switched to the flowing mode using any of the three methods:
1. Attaching a 'data' event handler to the stream
2. Calling the stream.resume() method
3. Calling the stream.pipe() method to send the data to a Writable.

When you use any of the above method the stream starts to flow. It doesn't care if the data listeners are attached to the stream and there's a possibility of losing the data. Internally, the read() method is called on the stream and whatever data that is being accumulated in the internal buffer is read and emitted to the listeners. The memory usage is quite low.

When you attach a readable listener on your stream, it takes priority over the data listener and hence your stream remains in the paused mode. In the paused mode, you've to explicitly read the data from the internal buffer by calling the read() method. When the readable data is available it keeps on getting accumulated in the internal buffer until the read() method is called explicitly or the stream is resumed. You can specify the size in bytes of the chunk to be read from the internal buffer or all the available data is returned. When read() is called data event is also emitted with the chunk of data read. After consuming this data, the internal buffer is emptied. So when you have multiple readable events attached and try to consume from the same internal buffer, you are not able to get the same data multiple times.

My suggestion to you would be have just one readable listener and multiple data listeners. Having a readable would give you the flexibility to read when you want without missing any data. And with the data event handlers, you would be able to get that data in all the handlers.

like image 175
Swati Anand Avatar answered Nov 15 '22 16:11

Swati Anand