ruby heroku signals unicorn

ruby - ¿Cómo puedo decirle al unicornio que entienda las señales de Heroku?



heroku dashboard login (2)

Tal vez has visto esto ...

2012-03-07T15:36:25+00:00 heroku[web.1]: Stopping process with SIGTERM 2012-03-07T15:36:36+00:00 heroku[web.1]: Stopping process with SIGKILL 2012-03-07T15:36:36+00:00 heroku[web.1]: Error R12 (Exit timeout) -> Process failed to exit within 10 seconds of SIGTERM 2012-03-07T15:36:38+00:00 heroku[web.1]: Process exited with status 137

Este es un problema bien conocido cuando se ejecuta unicornio en heroku ...

¿Puedo decirle a heroku que envíe SIGQUIT ? ¿O puedo decirle a unicornio que trate a SIGTERM como un elegante cierre?


Esto es un truco, pero he creado con éxito un archivo de configuración de unicornio que atrapa la señal TERM , lo que impide que el unicornio lo reciba y realice su apagado rápido. Mi manejador de señal luego envía la señal QUIT regreso a sí mismo para activar el apagado elegante del unicornio.

Probado con Ruby 1.9.2, Unicorn 4.0.1 y 4.2.1, Mac OS X.

listen 9292 worker_processes 1 # This is a hack. The code is run with ''before_fork'' so it runs # *after* Unicorn installs its own TERM signal handler (which makes # this highly dependent on the Unicorn implementation details). # # We install our own signal handler for TERM and simply re-send a QUIT # signal to our self. before_fork do |_server, _worker| Signal.trap ''TERM'' do puts ''intercepting TERM and sending myself QUIT instead'' Process.kill ''QUIT'', Process.pid end end

Una preocupación es que (creo) este manejador de señal es heredado por procesos de trabajo. Sin embargo, el proceso de trabajo instala su propio controlador TERM , que debe sobrescribir este, por lo que no esperaría ningún problema. (Ver Unicorn::HttpServer#init_worker_process @ lib/unicorn/http_server.rb:551 .

Editar: un detalle más, este bloque que instala el controlador de señal se ejecutará una vez por proceso de trabajo (porque before_fork ), pero esto simplemente redundante y no afectará nada.


Heroku ahora proporciona instrucciones para esto aquí: https://blog.heroku.com/archives/2013/2/27/unicorn_rails

Su sugerencia de archivo unicorn.rb es:

# config/unicorn.rb worker_processes 3 timeout 30 preload_app true before_fork do |server, worker| Signal.trap ''TERM'' do puts ''Unicorn master intercepting TERM and sending myself QUIT instead'' Process.kill ''QUIT'', Process.pid end defined?(ActiveRecord::Base) and ActiveRecord::Base.connection.disconnect! end after_fork do |server, worker| Signal.trap ''TERM'' do puts ''Unicorn worker intercepting TERM and doing nothing. Wait for master to sent QUIT'' end defined?(ActiveRecord::Base) and ActiveRecord::Base.establish_connection end