適当にググると以下のようなコードが出てきてこのように使っていたのだけれど、これだと worker が ready になる前に oldbin に QUIT を送ってしまう
before_fork do |server, worker|
old_pid = "#{server.config[:pid]}.oldbin"
if old_pid != server.pid
begin
sig = (worker.nr + 1) >= server.worker_processes ? :QUIT : :TTOU
Process.kill(sig, File.read(old_pid).to_i)
rescue Errno::ENOENT, Errno::ESRCH
end
end
end
ので以下のようになんとかした。
servers = []
def wait_for_workers_are_ready(servers, old_pid)
Thread.new do
loop do
unless servers.inject(false) {|memo, s| memo ||= !s.orig_app.nil? }
Process.kill(:QUIT, File.read(old_pid).to_i)
end
Thread.pass
sleep 3
end
end
end
after_fork do |server, worker|
servers << server
begin
old_pid = "#{server.config[:pid]}.oldbin"
if old_pid != server.pid && (worker.nr + 1) >= server.worker_processes
wait_for_workers_are_ready servers, old_pid
end
rescue Errno::ENOENT, Errno::ESRCH => e
$stderr.puts "#{e.class} #{e.message}"
end
end
美しくない。