unicorn Ruby/Rack server user+dev discussion/patches/pulls/bugs/help
 help / color / mirror / code / Atom feed
From: Suraj Kurapati <sunaku@gmail.com>
To: unicorn list <mongrel-unicorn@rubyforge.org>
Subject: Re: feature request - when_ready() hook
Date: Mon, 8 Mar 2010 14:58:10 -0800	[thread overview]
Message-ID: <cfbcd2f01003081458v4bb57b37j7e1233d212a8b1f0@mail.gmail.com> (raw)
In-Reply-To: <cfbcd2f00911301547i3cacbcdco6f2ee808fe9108ad@mail.gmail.com>

Hi Eric,

On Mon, Nov 30, 2009 at 3:47 PM, Suraj Kurapati wrote:
> from Capistrano, I send SIGUSR2 to the existing Unicorn master (which
> will become the old Unicorn master), wait 90 seconds, and then send
> SIGQUIT to the old Unicorn master. [...] The only thing I'm worried
> about is that I'll have to keep adjusting this timeout as the
> infrastructure my app depends upon becomes slower/faster.  A
> when_ready() hook would really do wonders for me

Inspired by your solution[1] to a recent question about forking, I
solved this problem by temporarily sneaking into the build_app! method
and killing the old Unicorn master after the Rails app has been built:

  before_fork do |server, worker|
    #
    # the following allows a new master process to incrementally
    # phase out the old master process with SIGTTOU to avoid a
    # thundering herd (especially in the "preload_app false" case)
    # when doing a transparent upgrade.  The last worker spawned
    # will then kill off the old master process with a SIGQUIT.
    #
    old_pid_file = server.config[:pid].to_s + '.oldbin'

    if File.exist? old_pid_file and
      server.pid != old_pid_file and
      worker.nr == server.worker_processes-1
    then
      #
      # wait until Rails app is built and ready to serve (we do this by
      # sneaking into Unicorn's build_app! method) by the last worker
      # process inside the new Unicorn before stopping old Unicorn
      #
      orig_meth_name = :build_app!
      orig_meth_impl = server.method(orig_meth_name)

      server_metaclass = class << server; self; end
      server_metaclass.class_eval do

        # replace Unicorn's method with our own sneaky version
        define_method orig_meth_name do

          # behave like Unicorn's original method
          orig_meth_impl.call

          # do our sneaky business! (kill the old Unicorn)
          begin
            Process.kill :QUIT, File.read(old_pid_file).to_i
          rescue Errno::ENOENT, Errno::ESRCH
            # ignore
          end

          # restore Unicorn's original method
          server_metaclass.class_eval do
            define_method orig_meth_name, orig_meth_impl
          end

        end
      end
    end
  end

Thanks for your help! :)

[1]: http://article.gmane.org/gmane.comp.lang.ruby.unicorn.general/425
_______________________________________________
Unicorn mailing list - mongrel-unicorn@rubyforge.org
http://rubyforge.org/mailman/listinfo/mongrel-unicorn
Do not quote signatures (like this one) or top post when replying


      reply	other threads:[~2010-03-09 12:24 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2009-11-26  4:50 feature request - when_ready() hook Suraj Kurapati
2009-11-26  6:05 ` Eric Wong
2009-11-26 19:05   ` Suraj Kurapati
2009-11-26 19:53     ` Eric Wong
2009-11-30 23:47       ` Suraj Kurapati
2010-03-08 22:58         ` Suraj Kurapati [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: https://yhbt.net/unicorn/

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=cfbcd2f01003081458v4bb57b37j7e1233d212a8b1f0@mail.gmail.com \
    --to=sunaku@gmail.com \
    --cc=mongrel-unicorn@rubyforge.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://yhbt.net/unicorn.git/

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).