2011-04-26 8 views
7

Me gustaría crear un daemon ruby ​​que se cierre con gracia con un comando kill. Me gustaría agregar una trampa de señal que esperaría hasta que #code that could take some time to run terminara antes de apagarse. ¿Cómo voy a añadir que a algo como esto:Ruby daemon con cierre limpio

pid = fork do 
    pid_file = "/tmp/pids/daemon6.pid" 
    File.open(pid, 'w'){ |f| f.write(Process.pid) } 
    loop do 
     begin 
     #code that could take some time to run 
     rescue Exception => e 
     Notifier.deliver_daemon_rescued_notification(e) 
     end 
     sleep(10) 
    end 
end 
Process.detach pid 

Además, sería mejor tener un guión que, en separado, como un guión de muertes por separado en vez de tener como parte del código del demonio? Como algo monit o God llamaría para detenerlo?

Agradezco cualquier sugerencia.

Respuesta

7

Usted puede coger Interrupt, así:

pid = fork do 
    begin 
    loop do 
     # do your thing 
     sleep(10) 
    end 
    rescue Interrupt => e 
    # clean up 
    end 
end 
Process.detach(pid) 

Usted puede hacer lo mismo con Signal.trap('INT') { ... }, pero con sleep involucrados creo que es más fácil de capturar una excepción.

Actualización: esta es una manera más tradicional de hacerlo, y se asegura de que el bucle siempre se termina un movimiento completo antes de que se detenga:

pid = fork do 
    stop = false 
    Signal.trap('INT') { stop = true } 
    until stop 
    # do your thing 
    sleep(10) 
    end 
end 

La desventaja es que siempre va a hacer el sleep , por lo que casi siempre habrá una demora hasta que el proceso se detenga después de que lo hayas matado. Probablemente pueda evitarlo durmiendo en ráfagas, o haciendo una combinación de las variantes (rescatando el Interrupt alrededor del sleep o algo así).

+0

Gracias por su respuesta theo, el problema es que la captura de interrupción no permitirá que termine el ciclo principal. Lo que me gustaría hacer es atrapar la interrupción, dejar que termine el ciclo si comenzó y luego limpiar y matar el proceso. – fflyer05

+0

He actualizado mi respuesta con otra forma de hacerlo que sale con mayor gracia (pero en cambio tiene problemas con 'sleep '). – Theo

+0

Eso funcionará muy bien. ¡Gracias! ¿Qué sucede si se retira la llamada de espera del ciclo de hasta? Pensé que el sueño de ruby ​​ya estaba en ráfagas para que la señal INT lo echara del sueño. De todos modos, el sueño adicional es un problema mucho más pequeño que el final de un proceso en el medio del ciclo. – fflyer05