4

I have a simple shell script written in Node.js and I'm trying to do some cleanup before the process exits (⌃C). I've written the following code but for some reason the cleanup function doesn't complete. Any ideas why?

if (keepAlive) {

   process.stdin.resume();

    ['exit', 'SIGINT'].forEach(function(signal) {

        process.on(signal, function() {

        console.log("Received Signal: '" + signal + "'. Cleaning up...");

        cleanup(function(err) {
          console.log('this function is called but does not finish')
          process.exit();
        });

      });

    });
else {
    process.exit();
}

I'm using Node v6.9.2

jwerre
  • 9,179
  • 9
  • 60
  • 69

2 Answers2

5

You can do this :

process.on("SIGTERM", () => {
    ayncFunction().finally(() => process.exit(0));
});

process.on("SIGINT", () => {
    ayncFunction().finally(() => process.exit(0));
});

process.on("exit", code => {
    console.log(`APP stopped !`);
});
achille-san
  • 71
  • 1
  • 5
  • It won't work, the event loop is dead by the time "SIGINT" is received. Did you try it yourself before posting, huh? – winwin Oct 19 '22 at 10:20
  • @winwin your comment is wrong. Async code can be run inside SIGINT handler. Event loop is disabled only at the moment we enter EXIT (final) handler. – Ivan Kleshnin Feb 04 '23 at 17:11
4

You can't reliably run async code from process.on('exit'). Here's a quote from the doc:

There is no way to prevent the exiting of the event loop at this point, and once all 'exit' listeners have finished running the Node.js process will terminate.

So, as soon as the exit listener returns (even though it is still trying to finish up it's async processing), then the process will exit.


For a SIGINT handler, you should be able to do anything you want because once there is a SIGINT handler registered, there is no default behavior to exit the process so the process will only exit when you tell it to. From the doc:

If one of these signals [SIGINT or SIGTERM] has a listener installed, its default behavior will be removed (Node.js will no longer exit).

This means you should be able to exit when your async processing is done if you write your async handling code properly (which you do not show in your question).

jfriend00
  • 683,504
  • 96
  • 985
  • 979
  • From what I can tell you're saying I should use `SIGINT` which is what I'm doing. Am I missing something? – jwerre Jan 25 '18 at 01:10
  • @jwerre - Yes, for non-Windows platforms, it SIGINT should work fine for Ctrl-C. See https://stackoverflow.com/questions/20165605/detecting-ctrlc-in-node-js for details. It also may be that your async code is not properly waiting for completion of the async operation before you call `process.exit()`. If you show us that async code, we could advise on that. – jfriend00 Jan 25 '18 at 01:13