2

I have a Node app doing some asynchronous things, and I can't take the chance that one of the many modules does something bad and gets stuck, so the app will never exit. (It just happened when sending log messages to a service.)

I can't use process.exit directly, because it will terminate no matter how many asynchronous operations are pending. Still I'd like to exit as early as possible, so this won't do:

function exit() {
    setTimeout(function() {
        process.exit(1);
    }, 10000);
}

Because that will wait 10 seconds, even if everything went ok and all async events finished after 1 second.

I'm considering checking if the event loop is empty except for this timer, then exit. That could possibly be done through some undocumented process methods, but I prefer avoiding shady stuff like that. Any ideas about a better way to solve this?

Community
  • 1
  • 1
ciscoheat
  • 3,719
  • 1
  • 35
  • 52

1 Answers1

6

You can set your timer to whatever you want the timeout duration to be for a "stuck" async operation.

Then .unref() the timer. That will keep the timer itself from keeping node.js from exiting so it will exit when all the async operations are done or the timer fires, whichever comes first.

function exit() {
    var t = setTimeout(function() {
        process.exit(1);
    }, 10000);
    // allow process to exist naturally before the timer if it is ready to
    t.unref();
}

Something tells me that a more controllable and robust solution would be to code more robustly on each individual async event. The kinds of things that can get stuck like an HTTP request of an external server have their own timeout settings so if you set them, then they will complete one way or the other on their own and you don't run the risk that your external timer might fire before the async operation completes when it wasn't even stuck, but just slow.

jfriend00
  • 683,504
  • 96
  • 985
  • 979
  • Good point about robust coding, however in this case the problem was that a WebSocket connection was kept open indefinitely unless closing it explicitly, so I couldn't take any chance. – ciscoheat May 25 '16 at 16:14
  • @ciscoheat - Why not implement a timeout on the webSocket connection directly if that's what you actually want? – jfriend00 May 25 '16 at 16:25
  • It was private (in the 3rd part module), I had no access to it and didn't want to hack it. – ciscoheat May 25 '16 at 16:34