diff options
author | Eric Wong <normalperson@yhbt.net> | 2009-03-18 01:59:17 -0700 |
---|---|---|
committer | Eric Wong <normalperson@yhbt.net> | 2009-03-18 14:30:46 -0700 |
commit | 29c6af908c2bd1109be175c34b89c45c8cc2f60b (patch) | |
tree | 076b9cf2a415504001f2aa63af1cc74bfd02052e | |
parent | 2373b663049df69a168f1e876e817a49d8ed8a7b (diff) | |
download | unicorn-29c6af908c2bd1109be175c34b89c45c8cc2f60b.tar.gz |
In nearly every app, if the current working directory disappears, the app becomes broken, sometimes subtly. It can be especially broken when preload_app is false (the default). So just shut ourselves down to spare ourselves the wasted CPU cycles on a dead app. As a (hopefully) pleasant side effect, this allows configurations with preload_app==false (the default) to do application code reloads via SIGHUP (in addition to unicorn config reloads).
-rw-r--r-- | SIGNALS | 2 | ||||
-rw-r--r-- | lib/unicorn.rb | 10 | ||||
-rw-r--r-- | lib/unicorn/configurator.rb | 4 |
3 files changed, 15 insertions, 1 deletions
@@ -7,6 +7,8 @@ processes are documented here as well. === Master Process * HUP - reload config file and gracefully restart all workers + If preload_app is false (the default), the application code + will be reloaded when workers are restarted as well. * INT/TERM - quick shutdown, kills all workers immediately diff --git a/lib/unicorn.rb b/lib/unicorn.rb index d442f63..4f7d417 100644 --- a/lib/unicorn.rb +++ b/lib/unicorn.rb @@ -53,6 +53,7 @@ module Unicorn @start_ctx = DEFAULT_START_CTX.dup @start_ctx.merge!(start_ctx) if start_ctx @app = app + @alive = true @mode = :idle @master_pid = $$ @workers = Hash.new @@ -165,7 +166,7 @@ module Unicorn $0 = "unicorn master" logger.info "master process ready" # test relies on this message begin - loop do + while @alive reap_all_workers case @mode when :idle @@ -352,6 +353,13 @@ module Unicorn return if @workers.size == @worker_processes (0...@worker_processes).each do |worker_nr| @workers.values.include?(worker_nr) and next + begin + Dir.chdir(@start_ctx[:cwd]) + rescue Errno::ENOENT => err + logger.fatal "#{err.inspect} (#{@start_ctx[:cwd]})" + @alive = false + return + end tempfile = Tempfile.new('') # as short as possible to save dir space tempfile.unlink # don't allow other processes to find or see it tempfile.sync = true diff --git a/lib/unicorn/configurator.rb b/lib/unicorn/configurator.rb index dd9ae3b..ae74c2b 100644 --- a/lib/unicorn/configurator.rb +++ b/lib/unicorn/configurator.rb @@ -194,6 +194,10 @@ module Unicorn # properly close/reopen sockets. Files opened for logging do not # have to be reopened as (unbuffered-in-userspace) files opened with # the File::APPEND flag are written to atomically on UNIX. + # + # In addition to reloading the unicorn-specific config settings, + # SIGHUP will reload application code in the working + # directory/symlink when workers are gracefully restarted. def preload_app(bool) case bool when TrueClass, FalseClass |