ciscoheat ciscoheat - 6 months ago 59
Node.js Question

Exit Node.js process after event loop is empty OR after timeout

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?

Answer

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.