2011-04-04 14 views
7

Tendré un proceso primario que se usa para controlar los reinicios del servidor web. Le indicará al niño que deje de escuchar nuevas solicitudes, el niño le indicará a los padres que ha dejado de escuchar, luego el padre le indicará al nuevo niño que puede comenzar a escuchar. De esta forma, podemos lograr menos de 100 ms de tiempo de inactividad para reiniciar ese nivel (también tengo un reinicio de nieto de tiempo de inactividad cero, pero eso no siempre es suficiente para reiniciar).Detectar cuando el proceso primario finaliza

El administrador de servicios matará al padre cuando sea hora de apagarlo. ¿Cómo puede el niño detectar que el padre ha terminado?

Las señales se envían usando stdin y stdout del proceso hijo. Tal vez puedo detectar el final de una transmisión stdin? Espero evitar un intervalo de sondeo. Además, me gustaría que esto sea una detección muy rápida si es posible.

Respuesta

5

¿Podría simplemente poner un exit listener en el proceso principal que señala a los niños?

Editar:
También se puede utilizar para llamar node-ffi (Node Foreign Function Interface) ...
prctl(PR_SET_PDEATHSIG, SIGHUP);
... en Linux. (man 2 prctl)

+0

Creo que esto va a funcionar. El padre muere cuando es hora de cerrar, pero estoy bastante seguro de que el oyente de salida seguirá funcionando. Quizás todavía puedo [verificar el id. De proceso principal cada pocos segundos] (http://stackoverflow.com/questions/5566009/node-js-parent-process-id) y si se convierte en el número 1, significa que el padre ha muerto. –

+3

Si se está cerrando, sus procesos recibirán 'SIGTERM' primero. Puede capturar esto y hacer la limpieza de esta manera también: 'process.on ('SIGTERM', function() { console.log ('Obtuve SIGTERM, saliendo ...'); // haga un poco de limpieza aquí. .. process.exit (0); }); ' – entropo

+0

Y sí, hacer que los hijos comprueben periódicamente si su' PPID' se convirtió en '1' es una buena alternativa para los casos en que el padre no salió limpiamente. Ver también: http: // stackoverflow.com/questions/269494/how-can-i-cause-a-child-process-to-exit-when-the-parent-does – entropo

6

es sólo para proporcionar un ejemplo de la solución nodo-FFI que entropo ha propuesto esta respuesta (arriba) (como se ha mencionado que funcionará en Linux):

Este es el proceso padre, es desove el niño y luego la salida después de 5 segundos:

var spawn = require('child_process').spawn; 
var node = spawn('node', [__dirname + '/child.js']); 
setTimeout(function(){process.exit(0)}, 5000); 

este es el proceso hijo (ubicado en child.js)

var FFI = require('node-ffi'); 
var current = new FFI.Library(null, {"prctl": ["int32", ["int32", "uint32"]]}) 

//1: PR_SET_PDEATHSIG, 15: SIGTERM 
var returned = current.prctl(1,15); 

process.on('SIGTERM',function(){ 
     //do something interesting 
     process.exit(1); 
}); 

doNotExit = function(){ 
     return true; 
}; 
setInterval(doNotExit, 500); 

sin la current.prctl (1,15) el niño correrá por siempre, incluso si el padre está muriendo. Aquí se indicará con un SIGTERM que se manejará correctamente.

+0

Para quienes implementan esta solución. No llame a process.exit (1) hasta que haya terminado. logger.warn ("SIGTERM. Saliendo graciosamente.", function() {process.exit (1);}) – itaifrenkel

2

Comienzo Node.JS desde una aplicación OSX nativa como trabajador en segundo plano. Para hacer que la salida Node.js cuando el proceso principal que consume Node.js stdout muere/salidas, hago lo siguiente:

// Watch parent exit when it dies 

process.stdout.resume(); 
process.stdout.on('end', function() { 
 process.exit(); 
}); 

fácil como eso, pero no estoy muy seguro de si se trata de lo que ha sido pidiendo ;-)

+0

Estaba luchando con este caso de uso y esto funciona de manera brillante. ¡Aclamaciones! – sak

13

una solución más simple podría ser mediante el registro de 'desconexión' en el proceso hijo

process.on('disconnect', function() { 
    console.log('parent exited') 
    process.exit(); 
}); 
+0

¡Gracias! Intenté todo y esta parece ser la única forma de detectar que tu proceso principal fue asesinado -9. –

+0

Estoy totalmente de acuerdo en que esta es una gran solución. En mi caso, estoy escuchando el evento SIGTERM desde el proceso principal y también (si pasa algo malo y necesito reiniciar el proceso principal) en el evento de desconexión. En mi caso, el problema es notable, porque el proceso hijo crea un puerto de espera del servidor, por lo que comenzar de nuevo causa "ERRADDRINUSE". Esto resuelve el problema :) – JakubKnejzlik

Cuestiones relacionadas