Doing a cleanup action just before Node.js exits

后端 未结 11 1367
时光说笑
时光说笑 2020-11-22 13:54

I want to tell Node.js to always do something just before it exits, for whatever reason — Ctrl+C, an exception, or any other reason.

I tried th

相关标签:
11条回答
  • 2020-11-22 14:16

    async-exit-hook seems to be the most up-to-date solution for handling this problem. It's a forked/re-written version of exit-hook that supports async code before exiting.

    0 讨论(0)
  • 2020-11-22 14:17

    In the case where the process was spawned by another node process, like:

    var child = spawn('gulp', ['watch'], {
        stdio: 'inherit',
    });
    

    And you try to kill it later, via:

    child.kill();
    

    This is how you handle the event [on the child]:

    process.on('SIGTERM', function() {
        console.log('Goodbye!');
    });
    
    0 讨论(0)
  • 2020-11-22 14:27

    Here's a nice hack for windows

    process.on('exit', async () => {
        require('fs').writeFileSync('./tmp.js', 'crash', 'utf-8')
    });
    
    0 讨论(0)
  • 2020-11-22 14:29

    UPDATE:

    You can register a handler for process.on('exit') and in any other case(SIGINT or unhandled exception) to call process.exit()

    process.stdin.resume();//so the program will not close instantly
    
    function exitHandler(options, exitCode) {
        if (options.cleanup) console.log('clean');
        if (exitCode || exitCode === 0) console.log(exitCode);
        if (options.exit) process.exit();
    }
    
    //do something when app is closing
    process.on('exit', exitHandler.bind(null,{cleanup:true}));
    
    //catches ctrl+c event
    process.on('SIGINT', exitHandler.bind(null, {exit:true}));
    
    // catches "kill pid" (for example: nodemon restart)
    process.on('SIGUSR1', exitHandler.bind(null, {exit:true}));
    process.on('SIGUSR2', exitHandler.bind(null, {exit:true}));
    
    //catches uncaught exceptions
    process.on('uncaughtException', exitHandler.bind(null, {exit:true}));
    
    0 讨论(0)
  • 2020-11-22 14:30

    The script below allows having a single handler for all exit conditions. It uses an app specific callback function to perform custom cleanup code.

    cleanup.js

    // Object to capture process exits and call app specific cleanup function
    
    function noOp() {};
    
    exports.Cleanup = function Cleanup(callback) {
    
      // attach user callback to the process event emitter
      // if no callback, it will still exit gracefully on Ctrl-C
      callback = callback || noOp;
      process.on('cleanup',callback);
    
      // do app specific cleaning before exiting
      process.on('exit', function () {
        process.emit('cleanup');
      });
    
      // catch ctrl+c event and exit normally
      process.on('SIGINT', function () {
        console.log('Ctrl-C...');
        process.exit(2);
      });
    
      //catch uncaught exceptions, trace, then exit normally
      process.on('uncaughtException', function(e) {
        console.log('Uncaught Exception...');
        console.log(e.stack);
        process.exit(99);
      });
    };
    

    This code intercepts uncaught exceptions, Ctrl+C and normal exit events. It then calls a single optional user cleanup callback function before exiting, handling all exit conditions with a single object.

    The module simply extends the process object instead of defining another event emitter. Without an app specific callback the cleanup defaults to a no op function. This was sufficient for my use where child processes were left running when exiting by Ctrl+C.

    You can easily add other exit events such as SIGHUP as desired. Note: per NodeJS manual, SIGKILL cannot have a listener. The test code below demonstrates various ways of using cleanup.js

    // test cleanup.js on version 0.10.21
    
    // loads module and registers app specific cleanup callback...
    var cleanup = require('./cleanup').Cleanup(myCleanup);
    //var cleanup = require('./cleanup').Cleanup(); // will call noOp
    
    // defines app specific callback...
    function myCleanup() {
      console.log('App specific cleanup code...');
    };
    
    // All of the following code is only needed for test demo
    
    // Prevents the program from closing instantly
    process.stdin.resume();
    
    // Emits an uncaught exception when called because module does not exist
    function error() {
      console.log('error');
      var x = require('');
    };
    
    // Try each of the following one at a time:
    
    // Uncomment the next line to test exiting on an uncaught exception
    //setTimeout(error,2000);
    
    // Uncomment the next line to test exiting normally
    //setTimeout(function(){process.exit(3)}, 2000);
    
    // Type Ctrl-C to test forced exit 
    
    0 讨论(0)
提交回复
热议问题