about 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:34 +0000
commitf1d33c80dd6c5650f960f7087f4e08f809754d34 (patch)
tree2a4cb6193499e70990259bc00a2771b94566cd80
parent78ba3899eb24d6893e34984b9f1c479c7e6c9be3 (diff)
downloadunicorn-f1d33c80dd6c5650f960f7087f4e08f809754d34.tar.gz
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
-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