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:56 +0000
commitcca4c46dd8cd72afedd9c5d024d47b4554f00c53 (patch)
treec87b932aeff41f8e19d2e7fae0072b8a1fac472e
parentd1818d26b0ca491dac861f3c2d9e249b665269a4 (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 f1d33c80dd6c5650f960f7087f4e08f809754d34)
-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 c231a4d..8f490bb 100644
--- a/lib/unicorn.rb
+++ b/lib/unicorn.rb
@@ -423,10 +423,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