Class | ActionController::Dispatcher |
In: |
vendor/rails/actionpack/lib/action_controller/dispatcher.rb
|
Parent: | Object |
Dispatches requests to the appropriate controller and takes care of reloading the app after each request when Dependencies.load? is true.
# File vendor/rails/actionpack/lib/action_controller/dispatcher.rb, line 8 8: def define_dispatcher_callbacks(cache_classes) 9: unless cache_classes 10: # Development mode callbacks 11: before_dispatch :reload_application 12: after_dispatch :cleanup_application 13: 14: ActionView::Helpers::AssetTagHelper.cache_asset_timestamps = false 15: end 16: 17: # Common callbacks 18: to_prepare :load_application_controller do 19: begin 20: require_dependency 'application' unless defined?(::ApplicationController) 21: rescue LoadError => error 22: raise unless error.message =~ /application\.rb/ 23: end 24: end 25: 26: if defined?(ActiveRecord) 27: after_dispatch :checkin_connections 28: to_prepare(:activerecord_instantiate_observers) { ActiveRecord::Base.instantiate_observers } 29: end 30: 31: after_dispatch :flush_logger if Base.logger && Base.logger.respond_to?(:flush) 32: 33: to_prepare do 34: I18n.reload! 35: end 36: end
Backward-compatible class method takes CGI-specific args. Deprecated in favor of Dispatcher.new(output, request, response).dispatch.
# File vendor/rails/actionpack/lib/action_controller/dispatcher.rb, line 40 40: def dispatch(cgi = nil, session_options = CgiRequest::DEFAULT_SESSION_OPTIONS, output = $stdout) 41: new(output).dispatch_cgi(cgi, session_options) 42: end
If the block raises, send status code as a last-ditch response.
# File vendor/rails/actionpack/lib/action_controller/dispatcher.rb, line 59 59: def failsafe_response(fallback_output, status, originating_exception = nil) 60: yield 61: rescue Exception => exception 62: begin 63: log_failsafe_exception(status, originating_exception || exception) 64: body = failsafe_response_body(status) 65: fallback_output.write "Status: #{status}\r\nContent-Type: text/html\r\n\r\n#{body}" 66: nil 67: rescue Exception => failsafe_error # Logger or IO errors 68: $stderr.puts "Error during failsafe response: #{failsafe_error}" 69: $stderr.puts "(originally #{originating_exception})" if originating_exception 70: end 71: end
# File vendor/rails/actionpack/lib/action_controller/dispatcher.rb, line 105 105: def initialize(output = $stdout, request = nil, response = nil) 106: @output, @request, @response = output, request, response 107: end
Add a preparation callback. Preparation callbacks are run before every request in development mode, and before the first request in production mode.
An optional identifier may be supplied for the callback. If provided, to_prepare may be called again with the same identifier to replace the existing callback. Passing an identifier is a suggested practice if the code adding a preparation block may be reloaded.
# File vendor/rails/actionpack/lib/action_controller/dispatcher.rb, line 52 52: def to_prepare(identifier = nil, &block) 53: @prepare_dispatch_callbacks ||= ActiveSupport::Callbacks::CallbackChain.new 54: callback = ActiveSupport::Callbacks::Callback.new(:prepare_dispatch, block, :identifier => identifier) 55: @prepare_dispatch_callbacks.replace_or_append!(callback) 56: end
# File vendor/rails/actionpack/lib/action_controller/dispatcher.rb, line 140 140: def call(env) 141: @request = RackRequest.new(env) 142: @response = RackResponse.new(@request) 143: dispatch 144: end
# File vendor/rails/actionpack/lib/action_controller/dispatcher.rb, line 175 175: def checkin_connections 176: # Don't return connection (and peform implicit rollback) if this request is a part of integration test 177: return if test_request? 178: ActiveRecord::Base.clear_active_connections! 179: end
Cleanup the application by clearing out loaded classes so they can be reloaded on the next request without restarting the server.
# File vendor/rails/actionpack/lib/action_controller/dispatcher.rb, line 156 156: def cleanup_application 157: ActiveRecord::Base.reset_subclasses if defined?(ActiveRecord) 158: ActiveSupport::Dependencies.clear 159: ActiveRecord::Base.clear_reloadable_connections! if defined?(ActiveRecord) 160: end
# File vendor/rails/actionpack/lib/action_controller/dispatcher.rb, line 120 120: def dispatch 121: if ActionController::Base.allow_concurrency 122: dispatch_unlocked 123: else 124: @@guard.synchronize do 125: dispatch_unlocked 126: end 127: end 128: end
# File vendor/rails/actionpack/lib/action_controller/dispatcher.rb, line 130 130: def dispatch_cgi(cgi, session_options) 131: if cgi ||= self.class.failsafe_response(@output, '400 Bad Request') { CGI.new } 132: @request = CgiRequest.new(cgi, session_options) 133: @response = CgiResponse.new(cgi) 134: dispatch 135: end 136: rescue Exception => exception 137: failsafe_rescue exception 138: end
# File vendor/rails/actionpack/lib/action_controller/dispatcher.rb, line 109 109: def dispatch_unlocked 110: begin 111: run_callbacks :before_dispatch 112: handle_request 113: rescue Exception => exception 114: failsafe_rescue exception 115: ensure 116: run_callbacks :after_dispatch, :enumerator => :reverse_each 117: end 118: end
# File vendor/rails/actionpack/lib/action_controller/dispatcher.rb, line 162 162: def flush_logger 163: Base.logger.flush 164: end
# File vendor/rails/actionpack/lib/action_controller/dispatcher.rb, line 166 166: def mark_as_test_request! 167: @test_request = true 168: self 169: end
# File vendor/rails/actionpack/lib/action_controller/dispatcher.rb, line 146 146: def reload_application 147: # Run prepare callbacks before every request in development mode 148: run_callbacks :prepare_dispatch 149: 150: Routing::Routes.reload 151: ActionController::Base.view_paths.reload! 152: end
# File vendor/rails/actionpack/lib/action_controller/dispatcher.rb, line 171 171: def test_request? 172: @test_request 173: end
# File vendor/rails/actionpack/lib/action_controller/dispatcher.rb, line 187 187: def failsafe_rescue(exception) 188: self.class.failsafe_response(@output, '500 Internal Server Error', exception) do 189: if @controller ||= defined?(::ApplicationController) ? ::ApplicationController : Base 190: @controller.process_with_exception(@request, @response, exception).out(@output) 191: else 192: raise exception 193: end 194: end 195: end