Class: ActionController::Dispatcher
- Includes:
- ActiveSupport::Callbacks
- Defined in:
- lib/action_controller/dispatcher.rb
Overview
Dispatches requests to the appropriate controller and takes care of reloading the app after each request when Dependencies.load? is true.
Constant Summary collapse
- @@guard =
Mutex.new
Class Method Summary collapse
- .define_dispatcher_callbacks(cache_classes) ⇒ Object
-
.dispatch(cgi = nil, session_options = CgiRequest::DEFAULT_SESSION_OPTIONS, output = $stdout) ⇒ Object
Backward-compatible class method takes CGI-specific args.
-
.failsafe_response(fallback_output, status, originating_exception = nil) ⇒ Object
If the block raises, send status code as a last-ditch response.
-
.to_prepare(identifier = nil, &block) ⇒ Object
Add a preparation callback.
Instance Method Summary collapse
- #call(env) ⇒ Object
- #checkin_connections ⇒ Object
-
#cleanup_application ⇒ Object
Cleanup the application by clearing out loaded classes so they can be reloaded on the next request without restarting the server.
- #dispatch ⇒ Object
- #dispatch_cgi(cgi, session_options) ⇒ Object
- #dispatch_unlocked ⇒ Object
- #flush_logger ⇒ Object
-
#initialize(output = $stdout, request = nil, response = nil) ⇒ Dispatcher
constructor
A new instance of Dispatcher.
- #mark_as_test_request! ⇒ Object
- #reload_application ⇒ Object
- #test_request? ⇒ Boolean
Constructor Details
#initialize(output = $stdout, request = nil, response = nil) ⇒ Dispatcher
Returns a new instance of Dispatcher.
103 104 105 |
# File 'lib/action_controller/dispatcher.rb', line 103 def initialize(output = $stdout, request = nil, response = nil) @output, @request, @response = output, request, response end |
Class Method Details
.define_dispatcher_callbacks(cache_classes) ⇒ Object
8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
# File 'lib/action_controller/dispatcher.rb', line 8 def define_dispatcher_callbacks(cache_classes) unless cache_classes # Development mode callbacks before_dispatch :reload_application after_dispatch :cleanup_application end # Common callbacks to_prepare :load_application_controller do begin require_dependency 'application' unless defined?(::ApplicationController) rescue LoadError => error raise unless error. =~ /application\.rb/ end end if defined?(ActiveRecord) after_dispatch :checkin_connections to_prepare(:activerecord_instantiate_observers) { ActiveRecord::Base.instantiate_observers } end after_dispatch :flush_logger if Base.logger && Base.logger.respond_to?(:flush) to_prepare do I18n.reload! end end |
.dispatch(cgi = nil, session_options = CgiRequest::DEFAULT_SESSION_OPTIONS, output = $stdout) ⇒ Object
Backward-compatible class method takes CGI-specific args. Deprecated in favor of Dispatcher.new(output, request, response).dispatch.
38 39 40 |
# File 'lib/action_controller/dispatcher.rb', line 38 def dispatch(cgi = nil, = CgiRequest::DEFAULT_SESSION_OPTIONS, output = $stdout) new(output).dispatch_cgi(cgi, ) end |
.failsafe_response(fallback_output, status, originating_exception = nil) ⇒ Object
If the block raises, send status code as a last-ditch response.
57 58 59 60 61 62 63 64 65 66 67 68 69 |
# File 'lib/action_controller/dispatcher.rb', line 57 def failsafe_response(fallback_output, status, originating_exception = nil) yield rescue Exception => exception begin log_failsafe_exception(status, originating_exception || exception) body = failsafe_response_body(status) fallback_output.write "Status: #{status}\r\nContent-Type: text/html\r\n\r\n#{body}" nil rescue Exception => failsafe_error # Logger or IO errors $stderr.puts "Error during failsafe response: #{failsafe_error}" $stderr.puts "(originally #{originating_exception})" if originating_exception end end |
.to_prepare(identifier = nil, &block) ⇒ Object
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.
50 51 52 53 54 |
# File 'lib/action_controller/dispatcher.rb', line 50 def to_prepare(identifier = nil, &block) @prepare_dispatch_callbacks ||= ActiveSupport::Callbacks::CallbackChain.new callback = ActiveSupport::Callbacks::Callback.new(:prepare_dispatch, block, :identifier => identifier) @prepare_dispatch_callbacks.replace_or_append!(callback) end |
Instance Method Details
#call(env) ⇒ Object
138 139 140 141 142 |
# File 'lib/action_controller/dispatcher.rb', line 138 def call(env) @request = RackRequest.new(env) @response = RackResponse.new(@request) dispatch end |
#checkin_connections ⇒ Object
174 175 176 177 178 |
# File 'lib/action_controller/dispatcher.rb', line 174 def checkin_connections # Don't return connection (and peform implicit rollback) if this request is a part of integration test return if test_request? ActiveRecord::Base.clear_active_connections! end |
#cleanup_application ⇒ Object
Cleanup the application by clearing out loaded classes so they can be reloaded on the next request without restarting the server.
155 156 157 158 159 |
# File 'lib/action_controller/dispatcher.rb', line 155 def cleanup_application ActiveRecord::Base.reset_subclasses if defined?(ActiveRecord) ActiveSupport::Dependencies.clear ActiveRecord::Base.clear_reloadable_connections! if defined?(ActiveRecord) end |
#dispatch ⇒ Object
118 119 120 121 122 123 124 125 126 |
# File 'lib/action_controller/dispatcher.rb', line 118 def dispatch if ActionController::Base.allow_concurrency dispatch_unlocked else @@guard.synchronize do dispatch_unlocked end end end |
#dispatch_cgi(cgi, session_options) ⇒ Object
128 129 130 131 132 133 134 135 136 |
# File 'lib/action_controller/dispatcher.rb', line 128 def dispatch_cgi(cgi, ) if cgi ||= self.class.failsafe_response(@output, '400 Bad Request') { CGI.new } @request = CgiRequest.new(cgi, ) @response = CgiResponse.new(cgi) dispatch end rescue Exception => exception failsafe_rescue exception end |
#dispatch_unlocked ⇒ Object
107 108 109 110 111 112 113 114 115 116 |
# File 'lib/action_controller/dispatcher.rb', line 107 def dispatch_unlocked begin run_callbacks :before_dispatch handle_request rescue Exception => exception failsafe_rescue exception ensure run_callbacks :after_dispatch, :enumerator => :reverse_each end end |
#flush_logger ⇒ Object
161 162 163 |
# File 'lib/action_controller/dispatcher.rb', line 161 def flush_logger Base.logger.flush end |
#mark_as_test_request! ⇒ Object
165 166 167 168 |
# File 'lib/action_controller/dispatcher.rb', line 165 def mark_as_test_request! @test_request = true self end |
#reload_application ⇒ Object
144 145 146 147 148 149 150 151 |
# File 'lib/action_controller/dispatcher.rb', line 144 def reload_application # Run prepare callbacks before every request in development mode run_callbacks :prepare_dispatch Routing::Routes.reload ActionController::Base.view_paths.reload! ActionView::Helpers::AssetTagHelper::AssetTag::Cache.clear end |
#test_request? ⇒ Boolean
170 171 172 |
# File 'lib/action_controller/dispatcher.rb', line 170 def test_request? @test_request end |