Hola, trato de que mi aplicación Rails ejecute un comando de sistema en
background, recuperando el pid del proceso creado. Además dicho proceso
externo dura mucho tiempo y no debe bloquear a la aplicación web.
He probado con todo lo que he visto: “system”, “exec”, %x[ ] y IO.popen.
Sin duda la que mejor pinta tiene es IO.popen, ya que devuelve un objeto
de
tipo “proceso” con métodos para obtener el pid, la salida del comando,
permite mandar datos al comando…
El caso es que al ejecutarlo me crea procesos zombies que sólo mueren
cuando
mato manualmente al irb o a webrick (depende de dónde ejecute el
programa).
Por poner un ejemplo, mi código Rails ejecuta en un momento dado:
proc = IO.popen(“sleep 30”)
-
La aplicación Rails no espera 30 segundos sino que continúa la
ejecución web
(esto es bueno y requisito mÃo, pues el comando puede durar horas aunque
en
este ejemplo sean sólo 30 segundos). -
Obtengo el pid sin más que “proc.pid”.
El problema es que cuando pasan esos 30 segundos el proceso “sleep”
queda
zombie:
ibc 26345 26255 0 02:35 pts/1 00:00:00 [sleep]
Hay dos formas de acabar con él:
-
Matando webrick o el servidor web que sea (no me sirve, claro).
-
Leyendo la salida del proceso o cerrándolo, de tal forma que el padre
“irb
o webrick” hace el “wait” y el hijo muere:
proc.readlines
ó
proc.close
Esto último en realidad no me sirve pues ambos métodos se quedan
esperando a
que el proceso acabe, lo que significa que se bloquea la aplicación
Rails
¡¡durante una hora o más!!.
En fin, que después de muchas pruebas y de leerme todo el API de IO no
encuentro forma de lanzar un comando en background que dura mucho tiempo
y
poder olvidarme de él (simplemente por el problema de que queda como
zombie
ocupando recursos).
¿A alguien se le ocurre algo? Muchas gracias por cualquier sugerencia.
PD: Si lanzo el comando con:
system “sleep 30 &”
desaparece completamente el problema del proceso zombie, es más, el
comando “sleep” sigue corriendo incluso aunque mate a webrick, lo cuál
es
perfecto para mi aplicación.
El único problema es que con “system” no tengo ni idea de cómo recuperar
el
pid del proceso creado (y me hace falta). Tal vez sea más fácil
solventar el
asunto por este lado, pero necesito averiguar el pid.
Gracias de nuevo.