Last active
November 2, 2016 17:11
-
-
Save misterdjules/3aa4c77d8f881ffccba3b6e6f0050d03 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
$ 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