Realizar una acción de limpieza justo antes de que salga Node.js

Resuelto Erel Segal-Halevi asked hace 11 años • 13 respuestas

Quiero decirle a Node.js que siempre haga algo justo antes de salir, por cualquier motivo. Ctrl+C , una excepción o cualquier otro motivo.

Probé esto:

process.on('exit', function (){
    console.log('Goodbye!');
});

Comencé el proceso, lo maté y no pasó nada. Lo comencé de nuevo, presioné Ctrl+ Cy todavía no pasó nada...

Erel Segal-Halevi avatar Dec 25 '12 22:12 Erel Segal-Halevi
Aceptado

ACTUALIZAR:

Puede registrar un controlador para `process.on('exit')` y en cualquier otro caso(`SIGINT` o excepción no controlada) para llamar a `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}));

Esto solo funciona si llama al código sincrónico dentro del controlador; de lo contrario, llamará al controlador indefinidamente.

Emil Condrea avatar Dec 25 '2012 18:12 Emil Condrea

El siguiente script permite tener un único controlador para todas las condiciones de salida. Utiliza una función de devolución de llamada específica de la aplicación para realizar un código de limpieza personalizado.

limpieza.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);
  });
};

Este código intercepta excepciones no detectadas, Ctrl+ Cy eventos de salida normales. Luego llama a una única función de devolución de llamada de limpieza de usuario opcional antes de salir, manejando todas las condiciones de salida con un solo objeto.

El módulo simplemente extiende el objeto de proceso en lugar de definir otro emisor de eventos. Sin una devolución de llamada específica de la aplicación, la limpieza tiene por defecto una función no operativa. Esto fue suficiente para mi uso donde los procesos secundarios se dejaban ejecutando al salir con Ctrl+ C.

Puede agregar fácilmente otros eventos de salida como SIGHUP, según lo desee. Nota: según el manual de NodeJS, SIGKILL no puede tener un oyente. El siguiente código de prueba demuestra varias formas de utilizar 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 
CanyonCasa avatar Feb 22 '2014 00:02 CanyonCasa

Esto captura todos los eventos de salida que puedo encontrar y que puedan manejarse. Parece bastante fiable y limpio hasta el momento.

[`exit`, `SIGINT`, `SIGUSR1`, `SIGUSR2`, `uncaughtException`, `SIGTERM`].forEach((eventType) => {
  process.on(eventType, cleanUpServer.bind(null, eventType));
})
light24bulbs avatar Mar 20 '2018 19:03 light24bulbs