aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJosé Valim <jose.valim@gmail.com>2010-01-14 19:53:07 +0100
committerJosé Valim <jose.valim@gmail.com>2010-01-15 12:24:30 +0100
commit8c8942ed4f2da52aa42ccd46560acb0b5fd37cb8 (patch)
tree976072122a45b4d050a0d6e798ae55ac3fea67a7
parent5a8e7287c542cbe82d3127cae83dab8571ab9114 (diff)
downloadrails-8c8942ed4f2da52aa42ccd46560acb0b5fd37cb8.tar.gz
rails-8c8942ed4f2da52aa42ccd46560acb0b5fd37cb8.tar.bz2
rails-8c8942ed4f2da52aa42ccd46560acb0b5fd37cb8.zip
Move Dispatcher setup to Railties and add instrumentation hook.
-rw-r--r--actionpack/lib/action_controller.rb2
-rw-r--r--actionpack/lib/action_controller/deprecated/dispatcher.rb31
-rw-r--r--actionpack/lib/action_controller/dispatch/dispatcher.rb52
-rw-r--r--actionpack/lib/action_controller/metal/instrumentation.rb2
-rw-r--r--actionpack/lib/action_controller/railtie.rb8
-rw-r--r--actionpack/lib/action_dispatch/middleware/callbacks.rb17
-rw-r--r--actionpack/lib/action_view/helpers/form_helper.rb2
-rw-r--r--actionpack/lib/action_view/railtie.rb6
-rw-r--r--actionpack/test/controller/dispatcher_test.rb80
-rw-r--r--actionpack/test/dispatch/callbacks_test.rb76
-rw-r--r--activerecord/lib/active_record/railtie.rb13
-rw-r--r--railties/lib/rails/bootstrap.rb21
-rw-r--r--railties/lib/rails/dispatcher.rb2
13 files changed, 193 insertions, 119 deletions
diff --git a/actionpack/lib/action_controller.rb b/actionpack/lib/action_controller.rb
index 42582c4525..8bc2cc79d2 100644
--- a/actionpack/lib/action_controller.rb
+++ b/actionpack/lib/action_controller.rb
@@ -39,7 +39,7 @@ module ActionController
autoload :Verification
end
- autoload :Dispatcher, 'action_controller/dispatch/dispatcher'
+ autoload :Dispatcher, 'action_controller/deprecated/dispatcher'
autoload :Integration, 'action_controller/deprecated/integration_test'
autoload :IntegrationTest, 'action_controller/deprecated/integration_test'
autoload :PerformanceTest, 'action_controller/deprecated/performance_test'
diff --git a/actionpack/lib/action_controller/deprecated/dispatcher.rb b/actionpack/lib/action_controller/deprecated/dispatcher.rb
new file mode 100644
index 0000000000..3da3c8ce7d
--- /dev/null
+++ b/actionpack/lib/action_controller/deprecated/dispatcher.rb
@@ -0,0 +1,31 @@
+module ActionController
+ class Dispatcher
+ cattr_accessor :prepare_each_request
+ self.prepare_each_request = false
+
+ class << self
+ def before_dispatch(*args, &block)
+ ActiveSupport::Deprecation.warn "ActionController::Dispatcher.before_dispatch is deprecated. " <<
+ "Please use ActionDispatch::Callbacks.before instead.", caller
+ ActionDispatch::Callbacks.before(*args, &block)
+ end
+
+ def after_dispatch(*args, &block)
+ ActiveSupport::Deprecation.warn "ActionController::Dispatcher.after_dispatch is deprecated. " <<
+ "Please use ActionDispatch::Callbacks.after instead.", caller
+ ActionDispatch::Callbacks.after(*args, &block)
+ end
+
+ def to_prepare(*args, &block)
+ ActiveSupport::Deprecation.warn "ActionController::Dispatcher.to_prepare is deprecated. " <<
+ "Please use ActionDispatch::Callbacks.to_prepare instead.", caller
+ ActionDispatch::Callbacks.after(*args, &block)
+ end
+
+ def new
+ ActiveSupport::Deprecation.warn "ActionController::Dispatcher.new is deprecated, use Rails.application instead."
+ Rails.application
+ end
+ end
+ end
+end
diff --git a/actionpack/lib/action_controller/dispatch/dispatcher.rb b/actionpack/lib/action_controller/dispatch/dispatcher.rb
deleted file mode 100644
index cf02757cf6..0000000000
--- a/actionpack/lib/action_controller/dispatch/dispatcher.rb
+++ /dev/null
@@ -1,52 +0,0 @@
-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
-
- 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
-
- 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) do
- ActiveRecord::Base.instantiate_observers
- end
- end
-
- if Base.logger && Base.logger.respond_to?(:flush)
- after_dispatch do
- Base.logger.flush
- end
- end
-
- to_prepare do
- I18n.reload!
- end
- end
-
- delegate :to_prepare, :before_dispatch, :around_dispatch, :after_dispatch,
- :to => ActionDispatch::Callbacks
-
- def new
- # DEPRECATE Rails application fallback
- Rails.application
- end
- end
- end
-end
diff --git a/actionpack/lib/action_controller/metal/instrumentation.rb b/actionpack/lib/action_controller/metal/instrumentation.rb
index e0c75c9e44..4549f6c451 100644
--- a/actionpack/lib/action_controller/metal/instrumentation.rb
+++ b/actionpack/lib/action_controller/metal/instrumentation.rb
@@ -66,7 +66,7 @@ module ActionController
module ClassMethods
# A hook which allows other frameworks to log what happened during
- # controller process action. This method should return an awway
+ # controller process action. This method should return an array
# with the messages to be added.
# :api: plugin
def log_process_action(controller) #:nodoc:
diff --git a/actionpack/lib/action_controller/railtie.rb b/actionpack/lib/action_controller/railtie.rb
index d4886ecefd..741101a210 100644
--- a/actionpack/lib/action_controller/railtie.rb
+++ b/actionpack/lib/action_controller/railtie.rb
@@ -69,12 +69,12 @@ module ActionController
app.config.middleware.insert_before(:"ActionDispatch::ParamsParser", middleware)
end
- # # Prepare dispatcher callbacks and run 'prepare' callbacks
+ # Prepare dispatcher callbacks and run 'prepare' callbacks
initializer "action_controller.prepare_dispatcher" do |app|
# TODO: This used to say unless defined?(Dispatcher). Find out why and fix.
+ # Notice that at this point, ActionDispatch::Callbacks were already loaded.
require 'rails/dispatcher'
-
- Dispatcher.define_dispatcher_callbacks(app.config.cache_classes)
+ ActionController::Dispatcher.prepare_each_request = true unless app.config.cache_classes
unless app.config.cache_classes
# Setup dev mode route reloading
@@ -85,7 +85,7 @@ module ActionController
app.reload_routes!
end
end
- ActionDispatch::Callbacks.before_dispatch { |callbacks| reload_routes.call }
+ ActionDispatch::Callbacks.before { |callbacks| reload_routes.call }
end
end
diff --git a/actionpack/lib/action_dispatch/middleware/callbacks.rb b/actionpack/lib/action_dispatch/middleware/callbacks.rb
index 49bc20f11f..8098933e01 100644
--- a/actionpack/lib/action_dispatch/middleware/callbacks.rb
+++ b/actionpack/lib/action_dispatch/middleware/callbacks.rb
@@ -1,4 +1,10 @@
module ActionDispatch
+ # Provide callbacks to be executed before and after the request dispatch.
+ #
+ # It also provides a to_prepare callback, which is performed in all requests
+ # in development by only once in production and notification callback for async
+ # operations.
+ #
class Callbacks
include ActiveSupport::Callbacks
@@ -29,12 +35,6 @@ module ActionDispatch
set_callback(:call, :after, *args, &block)
end
- class << self
- # DEPRECATED
- alias_method :before_dispatch, :before
- alias_method :after_dispatch, :after
- end
-
def initialize(app, prepare_each_request = false)
@app, @prepare_each_request = app, prepare_each_request
run_callbacks(:prepare)
@@ -43,7 +43,10 @@ module ActionDispatch
def call(env)
run_callbacks(:call) do
run_callbacks(:prepare) if @prepare_each_request
- @app.call(env)
+
+ ActiveSupport::Notifications.instrument "action_dispatch.callback" do
+ @app.call(env)
+ end
end
end
end
diff --git a/actionpack/lib/action_view/helpers/form_helper.rb b/actionpack/lib/action_view/helpers/form_helper.rb
index cd805061be..20cee46d02 100644
--- a/actionpack/lib/action_view/helpers/form_helper.rb
+++ b/actionpack/lib/action_view/helpers/form_helper.rb
@@ -1080,7 +1080,7 @@ module ActionView
# Add the submit button for the given form. When no value is given, it checks
# if the object is a new resource or not to create the proper label:
#
- # <% form_for @post do %>
+ # <% form_for @post do |f| %>
# <%= f.submit %>
# <% end %>
#
diff --git a/actionpack/lib/action_view/railtie.rb b/actionpack/lib/action_view/railtie.rb
index e368aab825..968dc7b25e 100644
--- a/actionpack/lib/action_view/railtie.rb
+++ b/actionpack/lib/action_view/railtie.rb
@@ -7,5 +7,11 @@ module ActionView
require "action_view/railties/subscriber"
subscriber ActionView::Railties::Subscriber.new
+
+ initializer "action_view.cache_asset_timestamps" do |app|
+ unless app.config.cache_classes
+ ActionView::Helpers::AssetTagHelper.cache_asset_timestamps = false
+ end
+ end
end
end \ No newline at end of file
diff --git a/actionpack/test/controller/dispatcher_test.rb b/actionpack/test/controller/dispatcher_test.rb
index 64f1ad7610..7e19bce3b7 100644
--- a/actionpack/test/controller/dispatcher_test.rb
+++ b/actionpack/test/controller/dispatcher_test.rb
@@ -1,73 +1,59 @@
require 'abstract_unit'
-class DispatcherTest < Test::Unit::TestCase
- Dispatcher = ActionController::Dispatcher
-
- class Foo
- cattr_accessor :a, :b
- end
+# Ensure deprecated dispatcher works
+class DeprecatedDispatcherTest < ActiveSupport::TestCase
+ class DummyApp
+ def call(env)
+ [200, {}, 'response']
+ end
+ end
def setup
- ENV['REQUEST_METHOD'] = 'GET'
-
- # Clear callbacks as they are redefined by Dispatcher#define_dispatcher_callbacks
ActionDispatch::Callbacks.reset_callbacks(:prepare)
ActionDispatch::Callbacks.reset_callbacks(:call)
-
- ActionController::Routing::Routes.stubs(:call).returns([200, {}, 'response'])
- Dispatcher.stubs(:require_dependency)
end
- def teardown
- ENV.delete 'REQUEST_METHOD'
- end
+ def test_assert_deprecated_to_prepare
+ a = nil
+
+ assert_deprecated do
+ ActionController::Dispatcher.to_prepare { a = 1 }
+ end
- def test_clears_dependencies_after_dispatch_if_in_loading_mode
- ActiveSupport::Dependencies.expects(:clear).once
- dispatch(false)
+ assert_nil a
+ dispatch
+ assert_equal 1, a
end
- def test_prepare_callbacks
- a = b = c = nil
- ActionDispatch::Callbacks.to_prepare { |*args| a = b = c = 1 }
- ActionDispatch::Callbacks.to_prepare { |*args| b = c = 2 }
- ActionDispatch::Callbacks.to_prepare { |*args| c = 3 }
+ def test_assert_deprecated_before_dispatch
+ a = nil
- # Ensure to_prepare callbacks are not run when defined
- assert_nil a || b || c
+ assert_deprecated do
+ ActionController::Dispatcher.before_dispatch { a = 1 }
+ end
- # Run callbacks
+ assert_nil a
dispatch
-
assert_equal 1, a
- assert_equal 2, b
- assert_equal 3, c
-
- # Make sure they are only run once
- a = b = c = nil
- dispatch
- assert_nil a || b || c
end
- def test_to_prepare_with_identifier_replaces
- ActionDispatch::Callbacks.to_prepare(:unique_id) { |*args| Foo.a, Foo.b = 1, 1 }
- ActionDispatch::Callbacks.to_prepare(:unique_id) { |*args| Foo.a = 2 }
+ def test_assert_deprecated_after_dispatch
+ a = nil
+
+ assert_deprecated do
+ ActionController::Dispatcher.after_dispatch { a = 1 }
+ end
+ assert_nil a
dispatch
- assert_equal 2, Foo.a
- assert_equal nil, Foo.b
+ assert_equal 1, a
end
private
- def dispatch(cache_classes = true)
- ActionController::Dispatcher.prepare_each_request = false
- Dispatcher.define_dispatcher_callbacks(cache_classes)
- @dispatcher ||= ActionDispatch::Callbacks.new(ActionController::Routing::Routes)
- @dispatcher.call({'rack.input' => StringIO.new(''), 'action_dispatch.show_exceptions' => false})
+ def dispatch(cache_classes = true)
+ @dispatcher ||= ActionDispatch::Callbacks.new(DummyApp.new, !cache_classes)
+ @dispatcher.call({'rack.input' => StringIO.new('')})
end
- def assert_subclasses(howmany, klass, message = klass.subclasses.inspect)
- assert_equal howmany, klass.subclasses.size, message
- end
end
diff --git a/actionpack/test/dispatch/callbacks_test.rb b/actionpack/test/dispatch/callbacks_test.rb
new file mode 100644
index 0000000000..8a2d56cfcc
--- /dev/null
+++ b/actionpack/test/dispatch/callbacks_test.rb
@@ -0,0 +1,76 @@
+require 'abstract_unit'
+
+class DispatcherTest < Test::Unit::TestCase
+ class Foo
+ cattr_accessor :a, :b
+ end
+
+ class DummyApp
+ def call(env)
+ [200, {}, 'response']
+ end
+ end
+
+ def setup
+ Foo.a, Foo.b = 0, 0
+ ActionDispatch::Callbacks.reset_callbacks(:prepare)
+ ActionDispatch::Callbacks.reset_callbacks(:call)
+ end
+
+ def test_prepare_callbacks
+ a = b = c = nil
+ ActionDispatch::Callbacks.to_prepare { |*args| a = b = c = 1 }
+ ActionDispatch::Callbacks.to_prepare { |*args| b = c = 2 }
+ ActionDispatch::Callbacks.to_prepare { |*args| c = 3 }
+
+ # Ensure to_prepare callbacks are not run when defined
+ assert_nil a || b || c
+
+ # Run callbacks
+ dispatch
+
+ assert_equal 1, a
+ assert_equal 2, b
+ assert_equal 3, c
+
+ # Make sure they are only run once
+ a = b = c = nil
+ dispatch
+ assert_nil a || b || c
+ end
+
+ def test_to_prepare_with_identifier_replaces
+ ActionDispatch::Callbacks.to_prepare(:unique_id) { |*args| Foo.a, Foo.b = 1, 1 }
+ ActionDispatch::Callbacks.to_prepare(:unique_id) { |*args| Foo.a = 2 }
+
+ dispatch
+ assert_equal 2, Foo.a
+ assert_equal 0, Foo.b
+ end
+
+ def test_before_and_after_callbacks
+ ActionDispatch::Callbacks.before { |*args| Foo.a += 1; Foo.b += 1 }
+ ActionDispatch::Callbacks.after { |*args| Foo.a += 1; Foo.b += 1 }
+
+ dispatch
+ assert_equal 2, Foo.a
+ assert_equal 2, Foo.b
+
+ dispatch
+ assert_equal 4, Foo.a
+ assert_equal 4, Foo.b
+ end
+
+ def test_should_send_an_instrumentation_callback_for_async_processing
+ ActiveSupport::Notifications.expects(:instrument).with("action_dispatch.callback")
+ dispatch
+ end
+
+ private
+
+ def dispatch(cache_classes = true)
+ @dispatcher ||= ActionDispatch::Callbacks.new(DummyApp.new, !cache_classes)
+ @dispatcher.call({'rack.input' => StringIO.new('')})
+ end
+
+end
diff --git a/activerecord/lib/active_record/railtie.rb b/activerecord/lib/active_record/railtie.rb
index 88d0aa624f..bc06333f1c 100644
--- a/activerecord/lib/active_record/railtie.rb
+++ b/activerecord/lib/active_record/railtie.rb
@@ -56,6 +56,19 @@ module ActiveRecord
initializer "active_record.load_observers" do
ActiveRecord::Base.instantiate_observers
+
+ ActionDispatch::Callbacks.to_prepare(:activerecord_instantiate_observers) do
+ ActiveRecord::Base.instantiate_observers
+ end
+ end
+
+ initializer "active_record.set_dispatch_hooks", :before => :set_clear_dependencies_hook do |app|
+ unless app.config.cache_classes
+ ActionDispatch::Callbacks.after do
+ ActiveRecord::Base.reset_subclasses
+ ActiveRecord::Base.clear_reloadable_connections!
+ end
+ end
end
# TODO: ActiveRecord::Base.logger should delegate to its own config.logger
diff --git a/railties/lib/rails/bootstrap.rb b/railties/lib/rails/bootstrap.rb
index 8a65b3fa98..b7cf70747a 100644
--- a/railties/lib/rails/bootstrap.rb
+++ b/railties/lib/rails/bootstrap.rb
@@ -80,10 +80,7 @@ module Rails
end
end
- # Sets the logger for Active Record, Action Controller, and Action Mailer
- # (but only for those frameworks that are to be loaded). If the framework's
- # logger is already set, it is not changed, otherwise it is set to use
- # RAILS_DEFAULT_LOGGER.
+ # Sets the logger for dependencies and cache store.
initializer :initialize_framework_logging do
ActiveSupport::Dependencies.logger ||= Rails.logger
Rails.cache.logger ||= Rails.logger
@@ -99,7 +96,7 @@ module Rails
# Loads support for "whiny nil" (noisy warnings when methods are invoked
# on +nil+ values) if Configuration#whiny_nils is true.
initializer :initialize_whiny_nils do
- require('active_support/whiny_nil') if config.whiny_nils
+ require 'active_support/whiny_nil' if config.whiny_nils
end
# Sets the default value for Time.zone
@@ -120,6 +117,8 @@ module Rails
# Set the i18n configuration from config.i18n but special-case for the load_path which should be
# appended to what's already set instead of overwritten.
initializer :initialize_i18n do
+ require 'active_support/i18n'
+
config.i18n.each do |setting, value|
if setting == :load_path
I18n.load_path += value
@@ -127,6 +126,18 @@ module Rails
I18n.send("#{setting}=", value)
end
end
+
+ ActionDispatch::Callbacks.to_prepare do
+ I18n.reload!
+ end
+ end
+
+ initializer :set_clear_dependencies_hook do
+ unless config.cache_classes
+ ActionDispatch::Callbacks.after do
+ ActiveSupport::Dependencies.clear
+ end
+ end
end
initializer :initialize_notifications do
diff --git a/railties/lib/rails/dispatcher.rb b/railties/lib/rails/dispatcher.rb
index 7f9a6221d9..5d383eacd1 100644
--- a/railties/lib/rails/dispatcher.rb
+++ b/railties/lib/rails/dispatcher.rb
@@ -20,5 +20,5 @@
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#++
-require 'action_controller/dispatch/dispatcher'
+require 'action_controller/deprecated/dispatcher'
Dispatcher = ActionController::Dispatcher