You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I wrote a config loader called milieu which has a feature that prints a table displaying the key, value, and value of all the config value. Here's an example from Node v5.5.0:
I upgraded to Node v6.0.0 and noticed that this table now looks like this:
When the library detects a --explain-config flag it prints the table and exits the program. Below is a snippet of code from the library that does the former.
Basically the printExplainTable method prints the table to process.stdout with console.log. The idea here was that stdout would block until the table is printed to the shell, then process.exit(0) is called to stop the server/program from starting.
It seems that stdout no longer blocks. If stdout does not block, is there a method to know when the stdout has been flushed? I tried using the 'drain' event the the stdout stream, but that doesn't seem to fire.
process.stdout has never been blocking. This is (and has been) a known thing for a while but it's been put a bit more front and center because of a recent update in libuv. Essentially the issue lies with how process.exit() relates to the Node.js event loop... specifically, process.exit() tells the Node.js process to exit as soon as possible, even if there is additional work still pending in the event loop -- such as i/o. Because the additional writes to stdout happen asynchronously, calling process.exit() short circuits the io.
There are a couple of approaches to work around it but the main approach is to not call process.exit(0). The Node.js event loop will exit naturally and gracefully if there is no other pending work to do. For instance, in the code example above, if the intent is to Node.js to exit gracefully after calling this.printExplainTable(), simply do not schedule any other work in the event loop (examples include timers, servers, file i/o, etc) and Node will exit on it's own once the work has been completed.
The issue is not unlike spinning up work in multiple threads then not waiting for those to complete before exiting the process. Work gets lost.
@jasnell Hmm, interesting. I figured this was a bit of a bad idea anyway. I suppose I need to remove this functionality. Is there no way to detect once stdout has been flushed?
Activity
jasnell commentedon Apr 27, 2016
process.stdout has never been blocking. This is (and has been) a known thing for a while but it's been put a bit more front and center because of a recent update in libuv. Essentially the issue lies with how
process.exit()relates to the Node.js event loop... specifically,process.exit()tells the Node.js process to exit as soon as possible, even if there is additional work still pending in the event loop -- such as i/o. Because the additional writes to stdout happen asynchronously, callingprocess.exit()short circuits the io.There are a couple of approaches to work around it but the main approach is to not call
process.exit(0). The Node.js event loop will exit naturally and gracefully if there is no other pending work to do. For instance, in the code example above, if the intent is to Node.js to exit gracefully after callingthis.printExplainTable(), simply do not schedule any other work in the event loop (examples include timers, servers, file i/o, etc) and Node will exit on it's own once the work has been completed.The issue is not unlike spinning up work in multiple threads then not waiting for those to complete before exiting the process. Work gets lost.
RobertWHurst commentedon Apr 27, 2016
@jasnell Hmm, interesting. I figured this was a bit of a bad idea anyway. I suppose I need to remove this functionality. Is there no way to detect once stdout has been flushed?
RobertWHurst commentedon Apr 27, 2016
Will close this as it's an issue with my program, not Node 😄
jasnell commentedon Apr 27, 2016
I am opening a PR to clarify the documentation around
process.exit(). See #6410