aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--actionpack/lib/action_controller/dispatch/dispatcher.rb100
-rw-r--r--actionpack/lib/action_controller/dispatch/middlewares.rb1
-rw-r--r--actionpack/lib/action_dispatch.rb1
-rw-r--r--actionpack/lib/action_dispatch/middleware/callbacks.rb40
-rw-r--r--actionpack/test/controller/dispatcher_test.rb34
-rw-r--r--railties/lib/console_app.rb5
-rw-r--r--railties/lib/initializer.rb1
7 files changed, 103 insertions, 79 deletions
diff --git a/actionpack/lib/action_controller/dispatch/dispatcher.rb b/actionpack/lib/action_controller/dispatch/dispatcher.rb
index 63866caed9..9ad1cadfd3 100644
--- a/actionpack/lib/action_controller/dispatch/dispatcher.rb
+++ b/actionpack/lib/action_controller/dispatch/dispatcher.rb
@@ -1,87 +1,65 @@
+require 'active_support/core_ext/module/delegation'
+
module ActionController
# Dispatches requests to the appropriate controller and takes care of
# reloading the app after each request when Dependencies.load? is true.
class Dispatcher
+ cattr_accessor :prepare_each_request
+ self.prepare_each_request = false
+
+ cattr_accessor :router
+ self.router = Routing::Routes
+
+ cattr_accessor :middleware
+ self.middleware = ActionDispatch::MiddlewareStack.new do |middleware|
+ middlewares = File.join(File.dirname(__FILE__), "middlewares.rb")
+ middleware.instance_eval(File.read(middlewares), middlewares, 1)
+ end
+
class << self
def define_dispatcher_callbacks(cache_classes)
unless cache_classes
+ # Run prepare callbacks before every request in development mode
+ self.prepare_each_request = true
+
# Development mode callbacks
- before_dispatch :reload_application
- after_dispatch :cleanup_application
+ ActionDispatch::Callbacks.before_dispatch do |app|
+ ActionController::Dispatcher.router.reload
+ end
+
+ ActionDispatch::Callbacks.after_dispatch do
+ # Cleanup the application before processing the current request.
+ ActiveRecord::Base.reset_subclasses if defined?(ActiveRecord)
+ ActiveSupport::Dependencies.clear
+ ActiveRecord::Base.clear_reloadable_connections! if defined?(ActiveRecord)
+ end
ActionView::Helpers::AssetTagHelper.cache_asset_timestamps = false
end
if defined?(ActiveRecord)
- to_prepare(:activerecord_instantiate_observers) { ActiveRecord::Base.instantiate_observers }
+ to_prepare(:activerecord_instantiate_observers) do
+ ActiveRecord::Base.instantiate_observers
+ end
end
- after_dispatch :flush_logger if Base.logger && Base.logger.respond_to?(:flush)
+ if Base.logger && Base.logger.respond_to?(:flush)
+ after_dispatch do
+ Base.logger.flush
+ end
+ end
to_prepare do
I18n.reload!
end
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.
- 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
+ delegate :to_prepare, :prepare_dispatch, :before_dispatch, :after_dispatch,
+ :to => ActionDispatch::Callbacks
- def run_prepare_callbacks
- new.send :run_callbacks, :prepare_dispatch
+ def new
+ @@middleware.build(@@router)
end
end
-
- cattr_accessor :router
- self.router = Routing::Routes
-
- cattr_accessor :middleware
- self.middleware = ActionDispatch::MiddlewareStack.new do |middleware|
- middlewares = File.join(File.dirname(__FILE__), "middlewares.rb")
- middleware.instance_eval(File.read(middlewares), middlewares, 1)
- end
-
- include ActiveSupport::Callbacks
- define_callbacks :prepare_dispatch, :before_dispatch, :after_dispatch
-
- def initialize
- @app = @@middleware.build(@@router)
- freeze
- end
-
- def call(env)
- run_callbacks :before_dispatch
- @app.call(env)
- ensure
- run_callbacks :after_dispatch, :enumerator => :reverse_each
- end
-
- def reload_application
- # Run prepare callbacks before every request in development mode
- run_callbacks :prepare_dispatch
-
- @@router.reload
- end
-
- def cleanup_application
- # Cleanup the application before processing the current request.
- ActiveRecord::Base.reset_subclasses if defined?(ActiveRecord)
- ActiveSupport::Dependencies.clear
- ActiveRecord::Base.clear_reloadable_connections! if defined?(ActiveRecord)
- end
-
- def flush_logger
- Base.logger.flush
- end
end
end
diff --git a/actionpack/lib/action_controller/dispatch/middlewares.rb b/actionpack/lib/action_controller/dispatch/middlewares.rb
index e4e3a704c0..b25ed3fd3f 100644
--- a/actionpack/lib/action_controller/dispatch/middlewares.rb
+++ b/actionpack/lib/action_controller/dispatch/middlewares.rb
@@ -3,6 +3,7 @@ use "Rack::Lock", :if => lambda {
}
use "ActionDispatch::ShowExceptions", lambda { ActionController::Base.consider_all_requests_local }
+use "ActionDispatch::Callbacks", lambda { ActionController::Dispatcher.prepare_each_request }
use "ActionDispatch::Rescue", lambda {
controller = (::ApplicationController rescue ActionController::Base)
# TODO: Replace with controller.action(:_rescue_action)
diff --git a/actionpack/lib/action_dispatch.rb b/actionpack/lib/action_dispatch.rb
index f3c91d8624..6fc4ad3f21 100644
--- a/actionpack/lib/action_dispatch.rb
+++ b/actionpack/lib/action_dispatch.rb
@@ -38,6 +38,7 @@ module ActionDispatch
autoload :Response, 'action_dispatch/http/response'
autoload :StatusCodes, 'action_dispatch/http/status_codes'
+ autoload :Callbacks, 'action_dispatch/middleware/callbacks'
autoload :ParamsParser, 'action_dispatch/middleware/params_parser'
autoload :Rescue, 'action_dispatch/middleware/rescue'
autoload :ShowExceptions, 'action_dispatch/middleware/show_exceptions'
diff --git a/actionpack/lib/action_dispatch/middleware/callbacks.rb b/actionpack/lib/action_dispatch/middleware/callbacks.rb
new file mode 100644
index 0000000000..0a2b4cf5f7
--- /dev/null
+++ b/actionpack/lib/action_dispatch/middleware/callbacks.rb
@@ -0,0 +1,40 @@
+module ActionDispatch
+ class Callbacks
+ include ActiveSupport::Callbacks
+ define_callbacks :prepare, :before, :after
+
+ class << self
+ # DEPRECATED
+ alias_method :prepare_dispatch, :prepare
+ alias_method :before_dispatch, :before
+ alias_method :after_dispatch, :after
+ 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.
+ def self.to_prepare(identifier = nil, &block)
+ @prepare_callbacks ||= ActiveSupport::Callbacks::CallbackChain.new
+ callback = ActiveSupport::Callbacks::Callback.new(:prepare, block, :identifier => identifier)
+ @prepare_callbacks.replace_or_append!(callback)
+ end
+
+ def initialize(app, prepare_each_request = false)
+ @app, @prepare_each_request = app, prepare_each_request
+ run_callbacks :prepare
+ end
+
+ def call(env)
+ run_callbacks :before
+ run_callbacks :prepare if @prepare_each_request
+ @app.call(env)
+ ensure
+ run_callbacks :after, :enumerator => :reverse_each
+ end
+ end
+end
diff --git a/actionpack/test/controller/dispatcher_test.rb b/actionpack/test/controller/dispatcher_test.rb
index b315232a7b..9fae1fcf63 100644
--- a/actionpack/test/controller/dispatcher_test.rb
+++ b/actionpack/test/controller/dispatcher_test.rb
@@ -6,20 +6,20 @@ class DispatcherTest < Test::Unit::TestCase
def setup
ENV['REQUEST_METHOD'] = 'GET'
- Dispatcher.middleware = ActionDispatch::MiddlewareStack.new do |middleware|
- middlewares = File.expand_path(File.join(File.dirname(__FILE__), "../../lib/action_controller/dispatch/middlewares.rb"))
- middleware.instance_eval(File.read(middlewares))
- end
-
# Clear callbacks as they are redefined by Dispatcher#define_dispatcher_callbacks
- Dispatcher.instance_variable_set("@prepare_dispatch_callbacks", ActiveSupport::Callbacks::CallbackChain.new)
- Dispatcher.instance_variable_set("@before_dispatch_callbacks", ActiveSupport::Callbacks::CallbackChain.new)
- Dispatcher.instance_variable_set("@after_dispatch_callbacks", ActiveSupport::Callbacks::CallbackChain.new)
+ ActionDispatch::Callbacks.instance_variable_set("@prepare_callbacks", ActiveSupport::Callbacks::CallbackChain.new)
+ ActionDispatch::Callbacks.instance_variable_set("@before_callbacks", ActiveSupport::Callbacks::CallbackChain.new)
+ ActionDispatch::Callbacks.instance_variable_set("@after_callbacks", ActiveSupport::Callbacks::CallbackChain.new)
+ @old_router, Dispatcher.router = Dispatcher.router, mock()
+ Dispatcher.router.stubs(:call).returns([200, {}, 'response'])
+ Dispatcher.router.stubs(:reload)
Dispatcher.stubs(:require_dependency)
end
def teardown
+ Dispatcher.router = @old_router
+ @dispatcher = nil
ENV.delete 'REQUEST_METHOD'
end
@@ -29,12 +29,12 @@ class DispatcherTest < Test::Unit::TestCase
end
def test_reloads_routes_before_dispatch_if_in_loading_mode
- ActionController::Routing::Routes.expects(:reload).once
+ Dispatcher.router.expects(:reload).once
dispatch(false)
end
def test_leaves_dependencies_after_dispatch_if_not_in_loading_mode
- ActionController::Routing::Routes.expects(:reload).never
+ Dispatcher.router.expects(:reload).never
ActiveSupport::Dependencies.expects(:clear).never
dispatch
@@ -55,7 +55,7 @@ class DispatcherTest < Test::Unit::TestCase
assert_nil a || b || c
# Run callbacks
- Dispatcher.run_prepare_callbacks
+ dispatch
assert_equal 1, a
assert_equal 2, b
@@ -72,16 +72,22 @@ class DispatcherTest < Test::Unit::TestCase
Dispatcher.to_prepare(:unique_id) { |*args| a = b = 1 }
Dispatcher.to_prepare(:unique_id) { |*args| a = 2 }
- Dispatcher.run_prepare_callbacks
+ dispatch
assert_equal 2, a
assert_equal nil, b
end
private
def dispatch(cache_classes = true)
- ActionController::Routing::RouteSet.any_instance.stubs(:call).returns([200, {}, 'response'])
+ ActionController::Dispatcher.prepare_each_request = false
Dispatcher.define_dispatcher_callbacks(cache_classes)
- Dispatcher.new.call({'rack.input' => StringIO.new('')})
+ Dispatcher.middleware = ActionDispatch::MiddlewareStack.new do |middleware|
+ middlewares = File.expand_path(File.join(File.dirname(__FILE__), "../../lib/action_controller/dispatch/middlewares.rb"))
+ middleware.instance_eval(File.read(middlewares))
+ end
+
+ @dispatcher ||= Dispatcher.new
+ @dispatcher.call({'rack.input' => StringIO.new(''), 'action_dispatch.show_exceptions' => false})
end
def assert_subclasses(howmany, klass, message = klass.subclasses.inspect)
diff --git a/railties/lib/console_app.rb b/railties/lib/console_app.rb
index c944d49205..42bf50e01e 100644
--- a/railties/lib/console_app.rb
+++ b/railties/lib/console_app.rb
@@ -26,8 +26,7 @@ end
#reloads the environment
def reload!
puts "Reloading..."
- dispatcher = ActionController::Dispatcher.new
- dispatcher.cleanup_application
- dispatcher.reload_application
+ ActionController::Dispatcher.new
+ ActionController::Dispatcher.router.reload
true
end
diff --git a/railties/lib/initializer.rb b/railties/lib/initializer.rb
index b16f42b8a0..4c6de48a65 100644
--- a/railties/lib/initializer.rb
+++ b/railties/lib/initializer.rb
@@ -632,7 +632,6 @@ Run `rake gems:install` to install the missing gems.
return unless configuration.frameworks.include?(:action_controller)
require 'dispatcher' unless defined?(::Dispatcher)
Dispatcher.define_dispatcher_callbacks(configuration.cache_classes)
- Dispatcher.run_prepare_callbacks
end
def disable_dependency_loading