about summary refs log tree commit homepage
diff options
context:
space:
mode:
authorEric Wong <normalperson@yhbt.net>2009-10-02 00:25:00 -0700
committerEric Wong <normalperson@yhbt.net>2009-10-02 00:25:42 -0700
commit62206b128f71f64a684a5e14103178dc6a516125 (patch)
tree8715ff4cf8bdbea673dfd78352421c593e0f30ed
parenteb619c04765ef31b0e88329cbfd138d24558776e (diff)
downloadunicorn-62206b128f71f64a684a5e14103178dc6a516125.tar.gz
We now give an example of how a before_fork hook can be used
to incrementally migrate off the old code base without hitting
a thundering herd (especially in the "preload_app false") case.

Also comment on the per-worker listen usage in the RDoc, not
just a hidden comment.
-rw-r--r--lib/unicorn/configurator.rb21
1 files changed, 17 insertions, 4 deletions
diff --git a/lib/unicorn/configurator.rb b/lib/unicorn/configurator.rb
index 7e66f60..bff8f7e 100644
--- a/lib/unicorn/configurator.rb
+++ b/lib/unicorn/configurator.rb
@@ -25,9 +25,26 @@ module Unicorn
   #     # as there's no need for the master process to hold a connection
   #     defined?(ActiveRecord::Base) and
   #       ActiveRecord::Base.connection.disconnect!
+  #
+  #     # 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 = "#{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
+  #
+  #     # optionally throttle the master from forking too quickly by sleeping
+  #     sleep 1
   #   end
   #
   #   after_fork do |server, worker|
+  #     # per-process listener ports for debugging/admin/migrations
   #     addr = "127.0.0.1:#{9293 + worker.nr}"
   #     server.listen(addr, :tries => -1, :delay => 5, :tcp_nopush => true)
   #
@@ -50,10 +67,6 @@ module Unicorn
       :worker_processes => 1,
       :after_fork => lambda { |server, worker|
           server.logger.info("worker=#{worker.nr} spawned pid=#{$$}")
-
-          # per-process listener ports for debugging/admin:
-          # addr = "127.0.0.1:#{8081 + worker.nr}"
-          # server.listen(addr, :tries => -1, :delay => 5)
         },
       :before_fork => lambda { |server, worker|
           server.logger.info("worker=#{worker.nr} spawning...")