tutorial - haciendo una acción de limpieza justo antes de que node.js salga
node js vs php (8)
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}));
Quiero decirle a node.js que siempre haga algo justo antes de que salga, por cualquier razón: Ctrl + C, excepción o cualquier otra razón
Intenté esto:
process.on(''exit'', function (){
console.log(''Goodbye!'');
});
Comenzó el proceso, lo mató, y no pasó nada; comenzó de nuevo, presionó Ctrl + C, y aún no pasó nada ...
"exit" es un evento que se activa cuando el nodo finaliza su bucle de eventos internamente, no se activa cuando finaliza el proceso externamente.
Lo que estás buscando es ejecutar algo en un SIGINT.
Los documentos en http://nodejs.org/api/process.html#process_signal_events dan un ejemplo:
Ejemplo de escucha de SIGINT:
// Start reading from stdin so we don''t exit.
process.stdin.resume();
process.on(''SIGINT'', function () {
console.log(''Got SIGINT. Press Control-D to exit.'');
});
Nota: esto parece interrumpir el sigint y necesitaría llamar a process.exit () cuando termine con su código.
El siguiente script permite tener un solo 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-C y eventos de salida normales. Luego llama a una única función opcional de devolución de llamada de limpieza del usuario 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 se establece de manera predeterminada en una función no op. Esto fue suficiente para mi uso donde los procesos secundarios se dejaron en ejecución al salir de 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 código de prueba a continuación muestra varias formas de usar 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
En el caso donde el proceso fue generado por otro proceso de nodo, como:
var child = spawn(''gulp'', [''watch''], {
stdio: ''inherit'',
});
Y tratas de matarlo después, a través de:
child.kill();
Así es como manejas el evento [en el niño]:
process.on(''SIGTERM'', function() {
console.log(''Goodbye!'');
});
Esto atrapa cada evento de salida que puedo encontrar que puede ser manejado. Parece bastante confiable y limpio hasta ahora.
[`exit`, `SIGINT`, `SIGUSR1`, `SIGUSR2`, `uncaughtException`, `SIGTERM`].forEach((eventType) => {
process.on(eventType, cleanUpServer.bind(null, eventType));
})
Solo quería mencionar el paquete death
aquí: https://github.com/jprichardson/node-death
Ejemplo:
var ON_DEATH = require(''death'')({uncaughtException: true}); //this is intentionally ugly
ON_DEATH(function(signal, err) {
//clean up code here
})
io.js tiene una exit
y un evento beforeExit
, que hace lo que quiere.
function fnAsyncTest(callback) {
require(''fs'').writeFile(''async.txt'', ''bye!'', callback);
}
function fnSyncTest() {
for (var i = 0; i < 10; i++) {}
}
function killProcess() {
if (process.exitTimeoutId) {
return;
}
process.exitTimeoutId = setTimeout(process.exit, 5000);
console.log(''process will exit in 5 seconds'');
fnAsyncTest(function() {
console.log(''async op. done'', arguments);
});
if (!fnSyncTest()) {
console.log(''sync op. done'');
}
}
// https://nodejs.org/api/process.html#process_signal_events
process.on(''SIGTERM'', killProcess);
process.on(''SIGINT'', killProcess);
process.on(''uncaughtException'', function(e) {
console.log(''[uncaughtException] app will be terminated: '', e.stack);
killProcess();
/**
* @https://nodejs.org/api/process.html#process_event_uncaughtexception
*
* ''uncaughtException'' should be used to perform synchronous cleanup before shutting down the process.
* It is not safe to resume normal operation after ''uncaughtException''.
* If you do use it, restart your application after every unhandled exception!
*
* You have been warned.
*/
});
console.log(''App is running...'');
console.log(''Try to press CTRL+C or SIGNAL the process with PID: '', process.pid);
process.stdin.resume();
// just for testing