0

I am so curious about the below program.This program push the letters 'a' through 'z', inclusive , into a readable stream only when the consumer requests. I understand from the docs that _read() implementation is called by internal Readable class methods. If you run this program from terminal using the command node app.js | head -c5 then we can see that _read() is only called 5 times when we only request 5 bytes and thus it prints only abcde.

I would like to know where in the Node source code this _read() implementation is called?. Or where in Node source code _read() is getting called 5 times when we request for 5 bytes of data?.

I am so curious to know this, if someone can help me figure out it that would be great.

var Readable = require('stream').Readable;
var rs = Readable();

var c = 97 - 1;

rs._read = function () {
    if (c >= 'z'.charCodeAt(0)) return rs.push(null);
    
    setTimeout(function () {
        rs.push(String.fromCharCode(++c));
    }, 100);
};

rs.pipe(process.stdout);

process.on('exit', function () {
    console.error('\n_read() called ' + (c - 97) + ' times');
});
process.stdout.on('error', process.exit);
user3656231
  • 431
  • 2
  • 7
  • 17

1 Answers1

0

The pipe function is the triggering point.

  • When you call pipe function, there's an on('data', ...) event triggered.
  • This event extracts data for the stream using your _read implementation.
  • Now your readable stream has the data populated.

About head command,

  • The command looks for output util -c characters. Say head -c 5 once 5 chars are printed, it signals the previous process to exit.
  • On receiving this signal, the node process runs the exit function and terminates, hence stops executing _read further and prints number of characters read until then.

Here's the Call Stack of _read function captured from VS Code:

enter image description here

Abhilash
  • 2,026
  • 17
  • 21
  • May I know how did you get this Stacktrace in VS code. – user3656231 Aug 30 '20 at 10:52
  • follow https://code.visualstudio.com/docs/nodejs/nodejs-debugging and look for "Call stack" in VSCode debug pane. – Abhilash Aug 30 '20 at 10:56
  • Because of the command "node app.js | head -c5" my _read() implementation called only 5 times and that means that it pushes only 5 bytes of data into the buffer. And hence we are getting only "abcde" as the output. But my assumption is that somewhere in Node source code there is a loop which will iterate only 5 times in this case and push only 5 bytes of data into the buffer. So I am expecting that kind of code somewhere in the source code. – user3656231 Aug 30 '20 at 11:00