From 8963e87841501c8e79b8434f8887e0d3a78b580c Mon Sep 17 00:00:00 2001 From: Eric Wong Date: Wed, 17 Feb 2010 19:24:09 -0800 Subject: graceful handling of bad config.ru + HUP w/ preload_app If preload_app is true and Unicorn is HUP-ed with a bad config.ru, then it would be possible to have Unicorn in a bad state and constantly throw 500 errors. We now detect syntax and load errors since they're likely to appear in modified Rackup files, and will restore the original app if reloading failed. --- lib/unicorn.rb | 4 +++- t/t0001-reload-bad-config.sh | 52 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 55 insertions(+), 1 deletion(-) create mode 100755 t/t0001-reload-bad-config.sh diff --git a/lib/unicorn.rb b/lib/unicorn.rb index e8d869b..6dec03e 100644 --- a/lib/unicorn.rb +++ b/lib/unicorn.rb @@ -731,6 +731,7 @@ module Unicorn end def load_config! + loaded_app = app begin logger.info "reloading config_file=#{config.config_file}" config[:listeners].replace(init_listeners) @@ -741,9 +742,10 @@ module Unicorn self.app = orig_app build_app! if preload_app logger.info "done reloading config_file=#{config.config_file}" - rescue => e + rescue StandardError, LoadError, SyntaxError => e logger.error "error reloading config_file=#{config.config_file}: " \ "#{e.class} #{e.message}" + self.app = loaded_app end end diff --git a/t/t0001-reload-bad-config.sh b/t/t0001-reload-bad-config.sh new file mode 100755 index 0000000..e1393ae --- /dev/null +++ b/t/t0001-reload-bad-config.sh @@ -0,0 +1,52 @@ +#!/bin/sh +. ./test-lib.sh +t_plan 7 "reload config.ru error with preload_app true" + +t_begin "setup and start" && { + unicorn_setup + rtmpfiles ru + + cat > $ru <<\EOF +use Rack::ContentLength +use Rack::ContentType, "text/plain" +x = { "hello" => "world" } +run lambda { |env| [ 200, {}, [ x.inspect << "\n" ] ] } +EOF + echo 'preload_app true' >> $unicorn_config + unicorn -D -c $unicorn_config $ru + unicorn_wait_start +} + +t_begin "hit with curl" && { + out=$(curl -sSf http://$listen/) + test x"$out" = x'{"hello"=>"world"}' +} + +t_begin "introduce syntax error in rackup file" && { + echo '...' >> $ru +} + +t_begin "reload signal succeeds" && { + kill -HUP $unicorn_pid + while ! egrep '(done|error) reloading' $r_err >/dev/null + do + sleep 1 + done + + grep 'error reloading' $r_err >/dev/null +} + +t_begin "hit with curl" && { + out=$(curl -sSf http://$listen/) + test x"$out" = x'{"hello"=>"world"}' +} + +t_begin "killing succeeds" && { + kill $unicorn_pid +} + +t_begin "check stderr" && { + check_stderr +} + +t_done -- cgit v1.2.3-24-ge0c7