So sending USR2 to Unicorn is awesome -- it starts up a new master with a new copy of your code and automatically picks up any changes. Sweet. My question is: how do I stop the old master? The apparently accepted way is in a before_fork:
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
The problem with this is that as soon as the new master (and new workers) are spawned, they kill the old master. So any requests to the site just sit there waiting for the new worker to start, usually for several seconds while the entire Rails stack loads.
If I remove my before_fork everything works as I would hope (from the client's point of view): I can reload my browser all day and every request is filled quickly, there's no indication of when the new master takes over (other than seeing my code changes appear now). But, the old master now hangs around until I manually send it a QUIT.
As far as I know there is no callback once a worker is done loading and ready to serve clients. That's really the callback I'm looking for. I could always create an initializer in Rails itself that looks for an old master and kills it, but that makes my heart hurt just thinking about it.
There must be a way!