Changeset 7640
- Timestamp:
- 09/26/07 01:24:07 (2 years ago)
- Files:
-
- trunk/actionpack/CHANGELOG (modified) (1 diff)
- trunk/actionpack/lib/action_controller/dispatcher.rb (copied) (copied from trunk/railties/lib/dispatcher.rb) (1 diff)
- trunk/actionpack/test/abstract_unit.rb (modified) (1 diff)
- trunk/actionpack/test/controller/dispatcher_test.rb (moved) (moved from trunk/railties/test/dispatcher_test.rb) (4 diffs)
- trunk/railties/CHANGELOG (modified) (1 diff)
- trunk/railties/lib/console_app.rb (modified) (1 diff)
- trunk/railties/lib/dispatcher.rb (modified) (1 diff)
- trunk/railties/Rakefile (modified) (1 diff)
- trunk/railties/test/console_app_test.rb (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
trunk/actionpack/CHANGELOG
r7608 r7640 1 1 *SVN* 2 3 * Move Railties' Dispatcher to ActionController::Dispatcher, introduce before_ and after_dispatch callbacks, and warm up to non-CGI requests. [Jeremy Kemper] 2 4 3 5 * The tag helper may bypass escaping. [Jeremy Kemper] trunk/actionpack/lib/action_controller/dispatcher.rb
r7475 r7640 1 #-- 2 # Copyright (c) 2004-2007 David Heinemeier Hansson 3 # 4 # Permission is hereby granted, free of charge, to any person obtaining 5 # a copy of this software and associated documentation files (the 6 # "Software"), to deal in the Software without restriction, including 7 # without limitation the rights to use, copy, modify, merge, publish, 8 # distribute, sublicense, and/or sell copies of the Software, and to 9 # permit persons to whom the Software is furnished to do so, subject to 10 # the following conditions: 11 # 12 # The above copyright notice and this permission notice shall be 13 # included in all copies or substantial portions of the Software. 14 # 15 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16 # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 17 # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18 # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 19 # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 20 # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 21 # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22 #++ 1 module ActionController 2 # Dispatches requests to the appropriate controller and takes care of 3 # reloading the app after each request when Dependencies.load? is true. 4 class Dispatcher 5 class << self 6 # Backward-compatible class method takes CGI-specific args. Deprecated 7 # in favor of Dispatcher.new(output, request, response).dispatch! 8 def dispatch(cgi = nil, session_options = CgiRequest::DEFAULT_SESSION_OPTIONS, output = $stdout) 9 new(output).dispatch_cgi(cgi, session_options) 10 end 23 11 24 # This class provides an interface for dispatching a CGI (or CGI-like) request 25 # to the appropriate controller and action. It also takes care of resetting 26 # the environment (when Dependencies.load? is true) after each request. 27 class Dispatcher 28 class << self 29 # Dispatch the given CGI request, using the given session options, and 30 # emitting the output via the given output. If you dispatch with your 31 # own CGI object be sure to handle the exceptions it raises on multipart 32 # requests (EOFError and ArgumentError). 33 def dispatch(cgi = nil, session_options = ActionController::CgiRequest::DEFAULT_SESSION_OPTIONS, output = $stdout) 34 controller = nil 35 if cgi ||= new_cgi(output) 36 request, response = ActionController::CgiRequest.new(cgi, session_options), ActionController::CgiResponse.new(cgi) 37 prepare_application 38 controller = ActionController::Routing::Routes.recognize(request) 39 controller.process(request, response).out(output) 12 # Declare a block to be called before each dispatch. 13 # Run in the order declared. 14 def before_dispatch(*method_names, &block) 15 callbacks[:before].concat method_names 16 callbacks[:before] << block if block_given? 40 17 end 41 rescue Exception => exception # errors from CGI dispatch 42 failsafe_response(cgi, output, '500 Internal Server Error', exception) do 43 controller ||= (ApplicationController rescue ActionController::Base) 44 controller.process_with_exception(request, response, exception).out(output) 18 19 # Declare a block to be called after each dispatch. 20 # Run in reverse of the order declared. 21 def after_dispatch(*method_names, &block) 22 callbacks[:after].concat method_names 23 callbacks[:after] << block if block_given? 45 24 end 46 ensure47 # Do not give a failsafe response here.48 reset_after_dispatch49 end50 25 51 # Reset the application by clearing out loaded controllers, views, actions, 52 # mailers, and so forth. This allows them to be loaded again without having 53 # to restart the server (WEBrick, FastCGI, etc.). 54 def reset_application! 55 ActiveRecord::Base.reset_subclasses if defined?(ActiveRecord) 56 57 Dependencies.clear 58 59 ActiveRecord::Base.clear_reloadable_connections! if defined?(ActiveRecord) 60 end 61 62 # Add a preparation callback. Preparation callbacks are run before every 63 # request in development mode, and before the first request in production 64 # mode. 65 # 66 # An optional identifier may be supplied for the callback. If provided, 67 # to_prepare may be called again with the same identifier to replace the 68 # existing callback. Passing an identifier is a suggested practice if the 69 # code adding a preparation block may be reloaded. 70 def to_prepare(identifier = nil, &block) 71 unless identifier.nil? 72 callback = preparation_callbacks.detect { |ident, _| ident == identifier } 73 74 if callback # Already registered: update the existing callback 75 callback[-1] = block 76 return 26 # Add a preparation callback. Preparation callbacks are run before every 27 # request in development mode, and before the first request in production 28 # mode. 29 # 30 # An optional identifier may be supplied for the callback. If provided, 31 # to_prepare may be called again with the same identifier to replace the 32 # existing callback. Passing an identifier is a suggested practice if the 33 # code adding a preparation block may be reloaded. 34 def to_prepare(identifier = nil, &block) 35 # Already registered: update the existing callback 36 if identifier 37 if callback = callbacks[:prepare].assoc(identifier) 38 callback[1] = block 39 else 40 callbacks[:prepare] << [identifier, block] 41 end 42 else 43 callbacks[:prepare] << block 77 44 end 78 45 end 79 46 80 preparation_callbacks << [identifier, block]81 82 return83 end84 85 private86 attr_accessor_with_default :preparation_callbacks, []87 attr_accessor_with_default :preparation_callbacks_run, false88 89 # CGI.new plus exception handling. CGI#read_multipart raises EOFError90 # if body.empty? or body.size != Content-Length and raises ArgumentError91 # if Content-Length is non-integer.92 def new_cgi(output)93 failsafe_response(nil, output, '400 Bad Request') { CGI.new }94 end95 96 def prepare_application97 if Dependencies.load?98 ActionController::Routing::Routes.reload99 self.preparation_callbacks_run = false100 end101 102 require_dependency 'application' unless Object.const_defined?(:ApplicationController)103 ActiveRecord::Base.verify_active_connections! if defined?(ActiveRecord)104 run_preparation_callbacks105 end106 107 def reset_after_dispatch108 reset_application! if Dependencies.load?109 end110 111 def run_preparation_callbacks112 return if preparation_callbacks_run113 preparation_callbacks.each { |_, callback| callback.call }114 self.preparation_callbacks_run = true115 end116 117 47 # If the block raises, send status code as a last-ditch response. 118 def failsafe_response( cgi, fallback_output, status,exception = nil)48 def failsafe_response(fallback_output, status, originating_exception = nil) 119 49 yield 120 rescue Exception 50 rescue Exception => exception 121 51 begin 122 log_failsafe_exception(cgi, status, exception) 123 52 log_failsafe_exception(status, originating_exception || exception) 124 53 body = failsafe_response_body(status) 125 if cgi 126 head = { 'status' => status, 'type' => 'text/html' } 127 128 # FIXME: using CGI differently than CGIResponse does breaks 129 # the Mongrel CGI wrapper. 130 if defined?(Mongrel) && cgi.is_a?(Mongrel::CGIWrapper) 131 # FIXME: set a dummy cookie so the Mongrel CGI wrapper will 132 # also consider @output_cookies (used for session cookies.) 133 head['cookie'] = [] 134 cgi.header(head) 135 fallback_output << body 136 else 137 cgi.out(head) { body } 138 end 139 else 140 fallback_output.write "Status: #{status}\r\nContent-Type: text/html\r\n\r\n#{body}" 141 end 54 fallback_output.write "Status: #{status}\r\nContent-Type: text/html\r\n\r\n#{body}" 142 55 nil 143 rescue Exception # Logger or IO errors 56 rescue Exception => failsafe_error # Logger or IO errors 57 $stderr.puts "Error during failsafe response: #{failsafe_error}" 58 $stderr.puts "(originally #{originating_exception})" if originating_exception 144 59 end 145 60 end 146 61 147 def failsafe_response_body(status) 148 error_path = "#{RAILS_ROOT}/public/#{status[0..3]}.html" 62 private 63 def failsafe_response_body(status) 64 error_path = "#{error_file_path}/#{status.to_s[0..3]}.html" 149 65 150 if File.exists?(error_path) 151 File.read(error_path) 152 else 153 "<html><body><h1>#{status}</h1></body></html>" 66 if File.exist?(error_path) 67 File.read(error_path) 68 else 69 "<html><body><h1>#{status}</h1></body></html>" 70 end 71 end 72 73 def log_failsafe_exception(status, exception) 74 message = "/!\ FAILSAFE /!\ #{Time.now}\n Status: #{status}\n" 75 message << " #{exception}\n #{exception.backtrace.join("\n ")}" if exception 76 failsafe_logger.fatal message 77 end 78 79 def failsafe_logger 80 if defined?(::RAILS_DEFAULT_LOGGER) && !::RAILS_DEFAULT_LOGGER.nil? 81 ::RAILS_DEFAULT_LOGGER 82 else 83 Logger.new($stderr) 84 end 85 end 86 end 87 88 cattr_accessor :error_file_path 89 self.error_file_path = "#{::RAILS_ROOT}/public" if defined? ::RAILS_ROOT 90 91 cattr_accessor :callbacks 92 self.callbacks = Hash.new { |h, k| h[k] = [] } 93 94 attr_accessor_with_default :unprepared, true 95 96 97 before_dispatch :reload_application 98 before_dispatch :prepare_application 99 after_dispatch :flush_logger 100 after_dispatch :cleanup_application 101 102 def initialize(output, request = nil, response = nil) 103 @output, @request, @response = output, request, response 104 end 105 106 def dispatch 107 run_callbacks :before 108 handle_request 109 rescue Exception => exception 110 failsafe_rescue exception 111 ensure 112 run_callbacks :after, :reverse_each 113 end 114 115 def dispatch_cgi(cgi, session_options) 116 if cgi ||= self.class.failsafe_response(@output, '400 Bad Request') { CGI.new } 117 @request = CgiRequest.new(cgi, session_options) 118 @response = CgiResponse.new(cgi) 119 dispatch 120 end 121 rescue Exception => exception 122 failsafe_rescue exception 123 end 124 125 def reload_application 126 if Dependencies.load? 127 Routing::Routes.reload 128 self.unprepared = true 129 end 130 end 131 132 def prepare_application(force = false) 133 require_dependency 'application' unless defined?(::ApplicationController) 134 ActiveRecord::Base.verify_active_connections! if defined?(ActiveRecord) 135 136 if unprepared || force 137 run_callbacks :prepare 138 self.unprepared = false 139 end 140 end 141 142 # Cleanup the application by clearing out loaded classes so they can 143 # be reloaded on the next request without restarting the server. 144 def cleanup_application(force = false) 145 if Dependencies.load? || force 146 ActiveRecord::Base.reset_subclasses if defined?(ActiveRecord) 147 Dependencies.clear 148 ActiveRecord::Base.clear_reloadable_connections! if defined?(ActiveRecord) 149 end 150 end 151 152 def flush_logger 153 RAILS_DEFAULT_LOGGER.flush if defined?(RAILS_DEFAULT_LOGGER) && RAILS_DEFAULT_LOGGER.respond_to?(:flush) 154 end 155 156 protected 157 def handle_request 158 @controller = Routing::Routes.recognize(@request) 159 @controller.process(@request, @response).out(@output) 160 end 161 162 def run_callbacks(kind, enumerator = :each) 163 callbacks[kind].send(enumerator) do |callback| 164 case callback 165 when Proc; callback.call(self) 166 when String, Symbol; send(callback) 167 when Array; callback[1].call(self) 168 else raise ArgumentError, "Unrecognized callback #{callback.inspect}" 169 end 154 170 end 155 171 end 156 172 157 def log_failsafe_exception(cgi, status, exception) 158 fell_back = cgi ? 'has cgi' : 'no cgi, fallback ouput' 159 message = "DISPATCHER FAILSAFE RESPONSE (#{fell_back}) #{Time.now}\n Status: #{status}\n" 160 message << " #{exception}\n #{exception.backtrace.join("\n ")}" if exception 161 failsafe_logger.fatal message 162 end 163 164 def failsafe_logger 165 if defined?(RAILS_DEFAULT_LOGGER) && !RAILS_DEFAULT_LOGGER.nil? 166 RAILS_DEFAULT_LOGGER 167 else 168 Logger.new($stderr) 173 def failsafe_rescue(exception) 174 self.class.failsafe_response(@output, '500 Internal Server Error', exception) do 175 if @controller ||= defined?(::ApplicationController) ? ::ApplicationController : Base 176 @controller.process_with_exception(@request, @response, exception).out(@output) 177 else 178 raise exception 179 end 169 180 end 170 181 end 171 182 end 172 183 end 173 174 Dispatcher.to_prepare :activerecord_instantiate_observers do175 ActiveRecord::Base.instantiate_observers176 end if defined?(ActiveRecord)trunk/actionpack/test/abstract_unit.rb
r6876 r7640 31 31 end 32 32 yield 33 rescue LoadError 33 rescue LoadError => load_error 34 raise unless load_error.message =~ /mocha/i 34 35 $stderr.puts "Skipping #{test_name} tests. `gem install mocha` and try again." 35 36 end trunk/actionpack/test/controller/dispatcher_test.rb
r7591 r7640 1 require "#{File.dirname(__FILE__)}/ abstract_unit"1 require "#{File.dirname(__FILE__)}/../abstract_unit" 2 2 3 3 uses_mocha 'dispatcher tests' do 4 4 5 $:.unshift File.dirname(__FILE__) + "/../../actionmailer/lib" 6 7 require 'stringio' 8 require 'cgi' 9 10 require 'dispatcher' 11 require 'action_controller' 12 require 'action_mailer' 13 5 require 'action_controller/dispatcher' 14 6 15 7 class DispatcherTest < Test::Unit::TestCase 8 Dispatcher = ActionController::Dispatcher 9 16 10 def setup 17 11 @output = StringIO.new 18 ENV['REQUEST_METHOD'] = "GET"12 ENV['REQUEST_METHOD'] = 'GET' 19 13 20 Dispatcher.send(:preparation_callbacks).clear 21 Dispatcher.send(:preparation_callbacks_run=, false) 22 23 Object.const_set 'ApplicationController', nil 14 Dispatcher.callbacks[:prepare].clear 15 @dispatcher = Dispatcher.new(@output) 24 16 end 25 17 26 18 def teardown 27 19 ENV['REQUEST_METHOD'] = nil 28 Object.send :remove_const, 'ApplicationController'29 20 end 30 21 … … 38 29 end 39 30 40 def test_ clears_dependencies_after_dispatch_if_not_in_loading_mode31 def test_leaves_dependencies_after_dispatch_if_not_in_loading_mode 41 32 Dependencies.stubs(:load?).returns(false) 42 33 … … 58 49 end 59 50 60 def test_preparation_callbacks 61 ActionController::Routing::Routes.stubs(:reload) 51 def test_reload_application_sets_unprepared_if_loading_dependencies 52 Dependencies.stubs(:load?).returns(false) 53 ActionController::Routing::Routes.expects(:reload).never 54 @dispatcher.unprepared = false 55 @dispatcher.send(:reload_application) 56 assert !@dispatcher.unprepared 62 57 63 old_mechanism = Dependencies.mechanism 64 58 Dependencies.stubs(:load?).returns(true) 59 ActionController::Routing::Routes.expects(:reload).once 60 @dispatcher.send(:reload_application) 61 assert @dispatcher.unprepared 62 end 63 64 def test_prepare_application_runs_callbacks_if_unprepared 65 65 a = b = c = nil 66 66 Dispatcher.to_prepare { a = b = c = 1 } 67 67 Dispatcher.to_prepare { b = c = 2 } 68 68 Dispatcher.to_prepare { c = 3 } 69 70 Dispatcher.send :prepare_application 71 69 70 # Skip the callbacks when already prepared. 71 @dispatcher.unprepared = false 72 @dispatcher.send :prepare_application 73 assert_nil a || b || c 74 75 # Perform the callbacks when unprepared. 76 @dispatcher.unprepared = true 77 @dispatcher.send :prepare_application 72 78 assert_equal 1, a 73 79 assert_equal 2, b 74 80 assert_equal 3, c 75 76 # When mechanism is :load, perform the callbacks each request: 77 Dependencies.mechanism = :load 78 a = b = c = nil 79 Dispatcher.send :prepare_application 80 assert_equal 1, a 81 assert_equal 2, b 82 assert_equal 3, c 83 81 84 82 # But when not :load, make sure they are only run once 85 83 a = b = c = nil 86 Dependencies.mechanism = :not_load 87 Dispatcher.send :prepare_application 88 assert_equal nil, a || b || c 89 ensure 90 Dependencies.mechanism = old_mechanism 84 @dispatcher.send :prepare_application 85 assert_nil a || b || c 91 86 end 92 87 93 88 def test_to_prepare_with_identifier_replaces 94 ActionController::Routing::Routes.stubs(:reload)95 96 89 a = b = nil 97 90 Dispatcher.to_prepare(:unique_id) { a = b = 1 } 98 91 Dispatcher.to_prepare(:unique_id) { a = 2 } 99 100 Dispatcher.send :prepare_application 92 93 @dispatcher.unprepared = true 94 @dispatcher.send :prepare_application 101 95 assert_equal 2, a 102 96 assert_equal nil, b … … 119 113 end 120 114 121 end # uses_mocha115 end trunk/railties/CHANGELOG
r7626 r7640 1 1 *SVN* 2 3 * Moved Dispatcher to ActionController::Dispatcher. [Jeremy Kemper] 2 4 3 5 * Changed the default logger from Ruby's own Logger with the clean_logger extensions to ActiveSupport::BufferedLogger for performance reasons [DHH]. (You can change it back with config.logger = Logger.new("/path/to/log", level).) trunk/railties/lib/console_app.rb
r7628 r7640 24 24 def reload! 25 25 puts "Reloading..." 26 returning Dispatcher.reset_application! do 27 Dispatcher.send :run_preparation_callbacks 28 end 26 dispatcher = ActionController::Dispatcher.new($stdout) 27 dispatcher.cleanup_application(true) 28 dispatcher.prepare_application(true) 29 true 29 30 end trunk/railties/lib/dispatcher.rb
r7626 r7640 21 21 # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22 22 #++ 23 24 # This class provides an interface for dispatching a CGI (or CGI-like) request 25 # to the appropriate controller and action. It also takes care of resetting 26 # the environment (when Dependencies.load? is true) after each request. 27 class Dispatcher 28 class << self 29 # Dispatch the given CGI request, using the given session options, and 30 # emitting the output via the given output. If you dispatch with your 31 # own CGI object be sure to handle the exceptions it raises on multipart 32 # requests (EOFError and ArgumentError). 33 def dispatch(cgi = nil, session_options = ActionController::CgiRequest::DEFAULT_SESSION_OPTIONS, output = $stdout) 34 controller = nil 35 if cgi ||= new_cgi(output) 36 request, response = ActionController::CgiRequest.new(cgi, session_options), ActionController::CgiResponse.new(cgi) 37 prepare_application 38 controller = ActionController::Routing::Routes.recognize(request) 39 controller.process(request, response).out(output) 40 end 41 rescue Exception => exception # errors from CGI dispatch 42 failsafe_response(cgi, output, '500 Internal Server Error', exception) do 43 controller ||= (ApplicationController rescue ActionController::Base) 44 controller.process_with_exception(request, response, exception).out(output) 45 end 46 ensure 47 # Do not give a failsafe response here 48 flush_logger 49 reset_after_dispatch 50 end 51 52 # Reset the application by clearing out loaded controllers, views, actions, 53 # mailers, and so forth. This allows them to be loaded again without having 54 # to restart the server (WEBrick, FastCGI, etc.). 55 def reset_application! 56 ActiveRecord::Base.reset_subclasses if defined?(ActiveRecord) 57 58 Dependencies.clear 59 60 ActiveRecord::Base.clear_reloadable_connections! if defined?(ActiveRecord) 61 end 62 63 # Add a preparation callback. Preparation callbacks are run before every 64 # request in development mode, and before the first request in production 65 # mode. 66 # 67 # An optional identifier may be supplied for the callback. If provided, 68 # to_prepare may be called again with the same identifier to replace the 69 # existing callback. Passing an identifier is a suggested practice if the 70 # code adding a preparation block may be reloaded. 71 def to_prepare(identifier = nil, &block) 72 unless identifier.nil? 73 callback = preparation_callbacks.detect { |ident, _| ident == identifier } 74 75 if callback # Already registered: update the existing callback 76 callback[-1] = block 77 return 78 end 79 end 80 81 preparation_callbacks << [identifier, block] 82 83 return 84 end 85 86 private 87 attr_accessor_with_default :preparation_callbacks, [] 88 attr_accessor_with_default :preparation_callbacks_run, false 89 90 # CGI.new plus exception handling. CGI#read_multipart raises EOFError 91 # if body.empty? or body.size != Content-Length and raises ArgumentError 92 # if Content-Length is non-integer. 93 def new_cgi(output) 94 failsafe_response(nil, output, '400 Bad Request') { CGI.new } 95 end 96 97 def prepare_application 98 if Dependencies.load? 99 ActionController::Routing::Routes.reload 100 self.preparation_callbacks_run = false 101 end 102 103 require_dependency 'application' unless Object.const_defined?(:ApplicationController) 104 ActiveRecord::Base.verify_active_connections! if defined?(ActiveRecord) 105 run_preparation_callbacks 106 end 107 108 def reset_after_dispatch 109 reset_application! if Dependencies.load? 110 end 111 112 def run_preparation_callbacks 113 return if preparation_callbacks_run 114 preparation_callbacks.each { |_, callback| callback.call } 115 self.preparation_callbacks_run = true 116 end 117 118 # If the block raises, send status code as a last-ditch response. 119 def failsafe_response(cgi, fallback_output, status, exception = nil) 120 yield 121 rescue Exception 122 begin 123 log_failsafe_exception(cgi, status, exception) 124 125 body = failsafe_response_body(status) 126 if cgi 127 head = { 'status' => status, 'type' => 'text/html' } 128 129 # FIXME: using CGI differently than CGIResponse does breaks 130 # the Mongrel CGI wrapper. 131 if defined?(Mongrel) && cgi.is_a?(Mongrel::CGIWrapper) 132 # FIXME: set a dummy cookie so the Mongrel CGI wrapper will 133 # also consider @output_cookies (used for session cookies.) 134 head['cookie'] = [] 135 cgi.header(head) 136 fallback_output << body 137 else 138 cgi.out(head) { body } 139 end 140 else 141 fallback_output.write "Status: #{status}\r\nContent-Type: text/html\r\n\r\n#{body}" 142 end 143 nil 144 rescue Exception # Logger or IO errors 145 end 146 end 147 148 def failsafe_response_body(status) 149 error_path = "#{RAILS_ROOT}/public/#{status[0..3]}.html" 150 151 if File.exists?(error_path) 152 File.read(error_path) 153 else 154 "<html><body><h1>#{status}</h1></body></html>" 155 end 156 end 157 158 def log_failsafe_exception(cgi, status, exception) 159 fell_back = cgi ? 'has cgi' : 'no cgi, fallback ouput' 160 message = "DISPATCHER FAILSAFE RESPONSE (#{fell_back}) #{Time.now}\n Status: #{status}\n" 161 message << " #{exception}\n #{exception.backtrace.join("\n ")}" if exception 162 failsafe_logger.fatal message 163 end 164 165 def failsafe_logger 166 if defined?(RAILS_DEFAULT_LOGGER) && !RAILS_DEFAULT_LOGGER.nil? 167 RAILS_DEFAULT_LOGGER 168 else 169 ActiveSupport::BufferedLogger.new($stderr) 170 end 171 end 172 173 def flush_logger 174 RAILS_DEFAULT_LOGGER.flush if defined?(RAILS_DEFAULT_LOGGER) && RAILS_DEFAULT_LOGGER.respond_to?(:flush) 175 end 176 end 177 end 178 179 Dispatcher.to_prepare :activerecord_instantiate_observers do 180 ActiveRecord::Base.instantiate_observers 181 end if defined?(ActiveRecord) 23 require 'action_controller/dispatcher' 24 Dispatcher = ActionController::Dispatcher trunk/railties/Rakefile
r7619 r7640 21 21 RUBY_FORGE_USER = "webster132" 22 22 23 24 task :default => :test 23 25 24 26 ## This is required until the regular test task trunk/railties/test/console_app_test.rb
r6898 r7640 2 2 3 3 require 'action_controller' # console_app uses 'action_controller/integration' 4 5 unless defined? ApplicationController 6 class ApplicationController < ActionController::Base; end 7 end 4 8 5 9 require 'dispatcher'