Por lo tanto, enviar el USR2 a Unicorn es increíble: inicia un nuevo maestro con una nueva copia de su código y automáticamente detecta cualquier cambio. Dulce. Mi pregunta es: ¿cómo detengo al viejo maestro? La forma aparentemente aceptado se encuentra en una before_fork:Reiniciar Unicornio con un USR2 - salir del viejo maestro
before_fork do |server,worker|
old_pid = '/var/www/current/tmp/pids/unicorn.pid.oldbin'
if File.exists?(old_pid) && server.pid != old_pid
begin
Process.kill("QUIT", File.read(old_pid).to_i)
rescue Errno::ENOENT, Errno::ESRCH
# someone else did our job for us
end
end
end
El problema con esto es que tan pronto como el nuevo maestro (y nuevos trabajadores) se generan, matan el viejo maestro. Por lo tanto, cualquier solicitud al sitio se queda allí esperando que comience el nuevo trabajador, generalmente durante varios segundos mientras se carga toda la pila de Rails.
Si elimino mi before_fork todo funciona como esperaría (desde el punto de vista del cliente): puedo recargar mi navegador todo el día y cada solicitud se completa rápidamente, no hay indicación de cuándo el nuevo maestro se hace cargo (otro que ver mis cambios de código aparecer ahora). Pero, el viejo maestro ahora se cuelga hasta que manualmente le envíe un QUIT.
Hasta donde sé, no hay devolución de llamada una vez que un trabajador termina de cargar y listo para atender a los clientes. Esa es realmente la devolución de llamada que estoy buscando. Siempre podría crear un inicializador en Rails que busque un viejo maestro y lo mate, pero eso me daña el corazón solo de pensarlo.
¡Debe haber una manera!
Estoy bastante seguro de que after_fork es llamado por los trabajadores una vez que hayan terminado de cargarse, probablemente puedas poner el código ahí .. –