diff --git a/lib/rack/adapter/rails.rb b/lib/rack/adapter/rails.rb index e5006e8..3ef87ef 100644 --- a/lib/rack/adapter/rails.rb +++ b/lib/rack/adapter/rails.rb @@ -64,6 +64,21 @@ module Rack serve_rails(env) end end + + def reload! + dependencies_mechanism = Dependencies.mechanism + dependencies_loaded = Dependencies.loaded.to_a + Dependencies.mechanism = :load + Dependencies.clear + dispatcher = ActionController::Dispatcher.new($stdout) + dispatcher.cleanup_application(true) + dispatcher.prepare_application(true) + dependencies_loaded.each {|a| Dependencies.associate_with a } + Dependencies.mechanism = dependencies_mechanism + true + rescue => e + STDERR.puts e + end protected diff --git a/lib/thin/controllers/cluster.rb b/lib/thin/controllers/cluster.rb index da88a4a..20f4ad7 100644 --- a/lib/thin/controllers/cluster.rb +++ b/lib/thin/controllers/cluster.rb @@ -58,6 +58,16 @@ module Thin sleep 0.1 # Let's breath a bit shall we ? start end + + def reload + with_each_server { |n| reload_server n } + end + + def reload_server(number) + log "Reloading server on #{server_id(number)} ... " + + run :reload, number + end def server_id(number) if socket diff --git a/lib/thin/controllers/controller.rb b/lib/thin/controllers/controller.rb index 4778bd5..11dccc1 100644 --- a/lib/thin/controllers/controller.rb +++ b/lib/thin/controllers/controller.rb @@ -78,6 +78,12 @@ module Thin Server.restart(@options[:pid]) end + + def reload + raise OptionRequired, :pid unless @options[:pid] + + Server.reload(@options[:pid]) + end def config config_file = @options.delete(:config) || raise(OptionRequired, :config) diff --git a/lib/thin/controllers/service.rb b/lib/thin/controllers/service.rb index 51f52af..dd290ff 100644 --- a/lib/thin/controllers/service.rb +++ b/lib/thin/controllers/service.rb @@ -30,6 +30,10 @@ module Thin def restart run :restart end + + def reload + run :reload + end def install(config_files_path=DEFAULT_CONFIG_PATH) if File.exist?(INITD_PATH) diff --git a/lib/thin/daemonizing.rb b/lib/thin/daemonizing.rb index ea15939..31525b9 100644 --- a/lib/thin/daemonizing.rb +++ b/lib/thin/daemonizing.rb @@ -47,7 +47,7 @@ module Thin write_pid_file - trap('HUP') { restart } + trap('QUIT') { restart } at_exit do log ">> Exiting!" remove_pid_file @@ -108,6 +108,10 @@ module Thin # Restart the server by sending HUP signal def restart(pid_file) + send_signal('QUIT', pid_file) + end + + def reload(pid_file) send_signal('HUP', pid_file) end diff --git a/lib/thin/runner.rb b/lib/thin/runner.rb index 56e87fa..1150ec5 100644 --- a/lib/thin/runner.rb +++ b/lib/thin/runner.rb @@ -5,7 +5,7 @@ module Thin # CLI runner. # Parse options and send command to the correct Controller. class Runner - COMMANDS = %w(start stop restart config) + COMMANDS = %w(start stop restart reload config) LINUX_ONLY_COMMANDS = %w(install) # Commands that wont load options from the config file diff --git a/lib/thin/server.rb b/lib/thin/server.rb index 14894d4..f3487b2 100644 --- a/lib/thin/server.rb +++ b/lib/thin/server.rb @@ -108,6 +108,7 @@ module Thin trap('INT') { stop } trap('TERM') { stop! } + trap('HUP') { reload! } # See http://rubyeventmachine.com/pub/rdoc/files/EPOLL.html EventMachine.epoll @@ -168,6 +169,11 @@ module Thin @running end + def reload! + log ">> Reloading ..." + @app.reload! if @app.respond_to?(:reload!) + end + protected def wait_for_connections_and_stop if @connector.empty?