This option can be used to implement custom behavior for handling worker exits. For example, let's say you have a specific request that crashes a worker process, which you expect to be due to a improperly programmed C extension. By modifying your worker to save request related data in a temporary file and using this option, you can get a record of what request is crashing the application, which will make debugging easier.
This is not a complete patch as it doesn't include tests, but before writing tests I wanted to see if this is something you'd consider including in unicorn. Example: after_worker_exit do |server, worker, status| server.logger.info "worker #{status.success? ? 'exit' : 'crash'}: #{status}" file = "request.#{status.pid}.txt" if File.exist?(file) do_something_with(File.read(file)) unless status.success? File.delete(file) end end --- lib/unicorn/configurator.rb | 14 ++++++++++++++ lib/unicorn/http_server.rb | 6 +++--- 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/lib/unicorn/configurator.rb b/lib/unicorn/configurator.rb index 3329c10..81589b0 100644 --- a/lib/unicorn/configurator.rb +++ b/lib/unicorn/configurator.rb @@ -41,6 +41,14 @@ class Unicorn::Configurator :before_exec => lambda { |server| server.logger.info("forked child re-executing...") }, + :after_worker_exit => lambda { |server, worker, status| + m = "reaped #{status.inspect} worker=#{worker.nr rescue 'unknown'}" + if status.success? + server.logger.info(m) + else + server.logger.error(m) + end + }, :pid => nil, :preload_app => false, :check_client_connection => false, @@ -151,6 +159,12 @@ def after_fork(*args, &block) set_hook(:after_fork, block_given? ? block : args[0]) end + # sets after_worker_exit hook to a given block. This block will be called + # by the master process after a worker exits. + def after_worker_exit(*args, &block) + set_hook(:after_worker_exit, block_given? ? block : args[0], 3) + end + # sets before_fork got be a given Proc object. This Proc # object will be called by the master process before forking # each worker. diff --git a/lib/unicorn/http_server.rb b/lib/unicorn/http_server.rb index 35bd100..567ee0e 100644 --- a/lib/unicorn/http_server.rb +++ b/lib/unicorn/http_server.rb @@ -14,7 +14,8 @@ class Unicorn::HttpServer attr_accessor :app, :timeout, :worker_processes, :before_fork, :after_fork, :before_exec, :listener_opts, :preload_app, - :orig_app, :config, :ready_pipe, :user + :orig_app, :config, :ready_pipe, :user, + :after_worker_exit attr_reader :pid, :logger include Unicorn::SocketHelper @@ -395,8 +396,7 @@ def reap_all_workers proc_name 'master' else worker = @workers.delete(wpid) and worker.close rescue nil - m = "reaped #{status.inspect} worker=#{worker.nr rescue 'unknown'}" - status.success? ? logger.info(m) : logger.error(m) + after_worker_exit.call(self, worker, status) end rescue Errno::ECHILD break -- 2.11.0 -- unsubscribe: unicorn-public+unsubscr...@bogomips.org archive: https://bogomips.org/unicorn-public/