summary refs log tree commit homepage
diff options
context:
space:
mode:
authorEric Wong <normalperson@yhbt.net>2010-07-16 08:25:32 +0000
committerEric Wong <normalperson@yhbt.net>2010-07-16 08:55:17 +0000
commit5a0506c2affd2f5abe6e7315121e67aa3e32b253 (patch)
tree5476af646fd3ca3f6759c56d149efd72d1c1a2b6
parenta965c0bb48d5b92373f939865212641d810c97d7 (diff)
In addition to SIGHUP, it should be possible to gradually bring
workers back up (to avoid overloading the machine) when rolling
back upgrades after SIGWINCH.

Noticed-by: Lawrence Pit
ref: http://mid.gmane.org/4C3F8C9F.2090903@gmail.com
(cherry picked from commit e75ee7615f9875db314a6403964e7b69a68b0521)
-rw-r--r--lib/unicorn.rb2
-rwxr-xr-xt/t0009-winch_ttin.sh59
2 files changed, 61 insertions, 0 deletions
diff --git a/lib/unicorn.rb b/lib/unicorn.rb
index cbb5520..e2d1ac1 100644
--- a/lib/unicorn.rb
+++ b/lib/unicorn.rb
@@ -422,10 +422,12 @@ module Unicorn
               respawn = false
               logger.info "gracefully stopping all workers"
               kill_each_worker(:QUIT)
+              self.worker_processes = 0
             else
               logger.info "SIGWINCH ignored because we're not daemonized"
             end
           when :TTIN
+            respawn = true
             self.worker_processes += 1
           when :TTOU
             self.worker_processes -= 1 if self.worker_processes > 0
diff --git a/t/t0009-winch_ttin.sh b/t/t0009-winch_ttin.sh
new file mode 100755
index 0000000..6e56e30
--- /dev/null
+++ b/t/t0009-winch_ttin.sh
@@ -0,0 +1,59 @@
+#!/bin/sh
+. ./test-lib.sh
+t_plan 8 "SIGTTIN succeeds after SIGWINCH"
+
+t_begin "setup and start" && {
+        unicorn_setup
+cat >> $unicorn_config <<EOF
+after_fork do |server, worker|
+  # test script will block while reading from $fifo,
+  File.open("$fifo", "wb") { |fp| fp.syswrite worker.nr.to_s }
+end
+EOF
+        unicorn -D -c $unicorn_config pid.ru
+        unicorn_wait_start
+        test 0 -eq $(cat $fifo) || die "worker.nr != 0"
+}
+
+t_begin "read worker pid" && {
+        orig_worker_pid=$(curl -sSf http://$listen/)
+        test -n "$orig_worker_pid" && kill -0 $orig_worker_pid
+}
+
+t_begin "stop all workers" && {
+        kill -WINCH $unicorn_pid
+}
+
+# we have to do this next step before delivering TTIN
+# signals aren't guaranteed to delivered in order
+t_begin "wait for worker to die" && {
+        i=0
+        while kill -0 $orig_worker_pid 2>/dev/null
+        do
+                i=$(( $i + 1 ))
+                test $i -lt 600 || die "timed out"
+                sleep 1
+        done
+}
+
+t_begin "start one worker back up" && {
+        kill -TTIN $unicorn_pid
+}
+
+t_begin "wait for new worker to start" && {
+        test 0 -eq $(cat $fifo) || die "worker.nr != 0"
+        new_worker_pid=$(curl -sSf http://$listen/)
+        test -n "$new_worker_pid" && kill -0 $new_worker_pid
+        test $orig_worker_pid -ne $new_worker_pid || \
+           die "worker wasn't replaced"
+}
+
+t_begin "killing succeeds" && {
+        kill $unicorn_pid
+}
+
+t_begin "check stderr" && check_stderr
+
+dbgcat r_err
+
+t_done