Skip to content

Instantly share code, notes, and snippets.

@garthk
Created August 2, 2012 04:38
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 garthk/3233620 to your computer and use it in GitHub Desktop.
Save garthk/3233620 to your computer and use it in GitHub Desktop.
Node.js does not detect process.stdout pipe closing
// this terminates: yes | head
// this hangs: node node-yes-simple.js | head
// per mhart, this is entirely expected
while(true) {
process.stdout.write('{"yes": "yes"}\n');
}
// Keep saying yes until interrupted or someone closes your output pipe:
var running = true;
function say_yes() {
if (running) {
process.stdout.write('{"yes": "yes"}\n');
process.nextTick(say_yes);
} else {
process.exit(0);
}
}
process.stdout.on('error', function(err) {
running = false;
if (err.code === 'EPIPE') {
// expected if output pipe closed, e.g. by `head`
process.exit(0);
} else {
process.stderr.write(JSON.stringify(err) + '\n');
process.exit(1);
}
});
@garthk
Copy link
Author

garthk commented Aug 2, 2012

Spotted while testing Trent's pipe solution for jsontool. Michael Hart is still getting EPIPE error events, though, hence epipebomb.

@mhart
Copy link

mhart commented Aug 2, 2012

You're starving the event loop with the infinite while.

Try this:

function writeYes() {
  process.stdout.write('{"yes": "yes"}\n');
  process.nextTick(writeYes);
}
writeYes();

(NB: The difference with the example in epipebomb is that the process there actually terminates so the events are processed after the for loop finishes - it's not infinite like the while examples here)

@garthk
Copy link
Author

garthk commented Aug 2, 2012

Updated. Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment