Skip to content

Instantly share code, notes, and snippets.

@misterdjules
Last active November 2, 2016 17:11
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save misterdjules/3aa4c77d8f881ffccba3b6e6f0050d03 to your computer and use it in GitHub Desktop.
Save misterdjules/3aa4c77d8f881ffccba3b6e6f0050d03 to your computer and use it in GitHub Desktop.
$ cat /var/tmp/test-stdout-blocking.js
// We want to write more than the buffer size for a pipe, so that all the data can't be written
// until the other end of the pipe reads from it. In this case we write 65KBs, as it seems the amount
// of data that can be written to process.stdout before actually blocking (the pipe buffer size) on
// OSX is 64KBs.
var buff = new Buffer(65 * 1024);
buff.fill('a');
// For node versions v4.x and later, not setting process.stdout._handle to be blocking will allow the node event loop
// to run as usual, because writes to the pipe will be retried when it's ready to be written to.
// Setting process.stdout._handle to be blocking will make the system calls that attempt to write
// to the pipe block the main thread, and the node event loop won't be able to run.
// For node versions v0.12.x and older, writes to process.std{out,err} are blocking by default.
//process.stdout._handle.setBlocking(true);
// This interval timer is used to be able to check whether the node
// event loop is still running. If the node event loop is still running,
// a message "node event loop still running" will be displayed on stderr
// every second.
setInterval(function interval() {
process.stderr.write('node event loop still running\n');
}, 1000).unref();
process.stdout.write(buff);
// This is used only for knowing when this process exits just by looking at the output
// when it's part of a pipeline with other processes that are still running.
process.on('exit', function onExit() {
process.stderr.write('exiting');
});
$ cat /var/tmp/python-start-sleep.py
import time
import sys
print "start"
# keep the process running but not reading for a while
time.sleep(600);
print "end"
$ node --version
v6.9.1
$ node /var/tmp/test-stdout-blocking.js| python /var/tmp/python-start-sleep.py
start
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
node event loop still running # Here the event loop is running because writes on process.stdout._handle are not blocking, and they are retried on the next turn of the event loop when they fail due to the pipe's buffer being full.
node event loop still running
^CTraceback (most recent call last):
File "/var/tmp/python-start-sleep.py", line 10, in <module>
time.sleep(600);
KeyboardInterrupt
$ vi /var/tmp/test-stdout-blocking.js # proces.stdout._handle.setBlocking(true) is "uncommented"
$ cat /var/tmp/test-stdout-blocking.js
// We want to write more than the high watermark for a pipe, so that all the data can't be written
// until the other end of the pipe reads from it.
var buff = new Buffer(1 * 1024 * 1024);
buff.fill('a');
// Not setting process.stdout._handle to be blocking will allow the node event loop
// to run as usual, because writes to the pipe will be retried when it's ready to be written to.
// Setting process.stdout._handle to be blocking will make the system calls that attempt to write
// to the pipe block the main thread, and the node event loop won't be able to run.
process.stdout._handle.setBlocking(true);
// This interval timer is used to be able to check whether the node
// event loop is still running. If the node event loop is still running,
// a message "node event loop still running" will be displayed on stderr
// every second.
setInterval(function interval() {
process.stderr.write('node event loop still running\n');
}, 1000).unref();
process.stdout.write(buff);
// This is used only for knowing when this process exits just by looking at the output
// when it's part of a pipeline with other processes that are still running.
process.on('exit', function onExit() {
process.stderr.write('exiting');
});
$ node /var/tmp/test-stdout-blocking.js| python /var/tmp/python-start-sleep.py
start
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
^CTraceback (most recent call last):
File "/var/tmp/python-start-sleep.py", line 10, in <module>
time.sleep(600);
KeyboardInterrupt
# Here the event loop is __not__ running because writes on process.stdout._handle are blocking, and they prevent the event loop from making any progress. Timers, immediates, and any other asynchronous operation that doesn't run on the thread pool are stalled.
$
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment