LoginSignup
5

More than 5 years have passed since last update.

unicorn で graceful restart するときに worker ready を待つ

Last updated at Posted at 2015-11-19

適当にググると以下のようなコードが出てきてこのように使っていたのだけれど、これだと 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

美しくない。

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5