Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

process.stdout not blocking in node v6.0.0? #6409

Closed
RobertWHurst opened this issue Apr 27, 2016 · 4 comments
Closed

process.stdout not blocking in node v6.0.0? #6409

RobertWHurst opened this issue Apr 27, 2016 · 4 comments

Comments

@RobertWHurst
Copy link

RobertWHurst commented Apr 27, 2016

  • v6.0.0:
  • OS X 10.11.4:
  • process:

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:
screen shot 2016-04-26 at 8 25 15 pm

I upgraded to Node v6.0.0 and noticed that this table now looks like this:
screen shot 2016-04-26 at 8 49 38 pm

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.

...
if (this.argv['explain-config']) {
  delete this.argv['explain-config'];
  this.printExplainTable();
  process.exit(0);
}
...

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.

Seems like a bug. Any thoughts?

@jasnell
Copy link
Member

jasnell commented 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, 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.

@RobertWHurst
Copy link
Author

@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
Copy link
Author

RobertWHurst commented Apr 27, 2016

Will close this as it's an issue with my program, not Node 😄

@jasnell
Copy link
Member

jasnell commented Apr 27, 2016

I am opening a PR to clarify the documentation around process.exit(). See #6410

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants