Replace AD::Callbacks.to_prepare with AD::Reloader.to_prepare

Signed-off-by: José Valim <jose.valim@gmail.com>
This commit is contained in:
John Firebaugh 2010-12-19 15:58:58 -08:00 committed by José Valim
parent 0f7c970e4f
commit 435bccda93
9 changed files with 34 additions and 96 deletions

View File

@ -1,32 +1,14 @@
module ActionDispatch module ActionDispatch
# Provide callbacks to be executed before and after the request dispatch. # 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 class Callbacks
include ActiveSupport::Callbacks include ActiveSupport::Callbacks
define_callbacks :call, :rescuable => true define_callbacks :call, :rescuable => true
define_callbacks :prepare, :scope => :name
# Add a preparation callback. Preparation callbacks are run before every
# request in development mode, and before the first request in production mode.
#
# If a symbol with a block is given, the symbol is used as an identifier.
# That allows to_prepare to 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(*args, &block) def self.to_prepare(*args, &block)
first_arg = args.first ActiveSupport::Deprecation.warn "ActionDispatch::Callbacks.to_prepare is deprecated. " <<
if first_arg.is_a?(Symbol) && block_given? "Please use ActionDispatch::Reloader.to_prepare instead."
remove_method :"__#{first_arg}" if method_defined?(:"__#{first_arg}") ActionDispatch::Reloader.to_prepare(*args, &block)
define_method :"__#{first_arg}", &block
set_callback(:prepare, :"__#{first_arg}")
else
set_callback(:prepare, *args, &block)
end
end end
def self.before(*args, &block) def self.before(*args, &block)
@ -37,14 +19,13 @@ module ActionDispatch
set_callback(:call, :after, *args, &block) set_callback(:call, :after, *args, &block)
end end
def initialize(app, prepare_each_request = false) def initialize(app, unused = nil)
@app, @prepare_each_request = app, prepare_each_request ActiveSupport::Deprecation.warn "Passing a second argument to ActionDispatch::Callbacks.new is deprecated." unless unused.nil?
_run_prepare_callbacks @app = app
end end
def call(env) def call(env)
_run_call_callbacks do _run_call_callbacks do
_run_prepare_callbacks if @prepare_each_request
@app.call(env) @app.call(env)
end end
end end

View File

@ -1,6 +1,6 @@
require 'abstract_unit' require 'abstract_unit'
class DispatcherTest < Test::Unit::TestCase class DispatcherTest < ActiveSupport::TestCase
class Foo class Foo
cattr_accessor :a, :b cattr_accessor :a, :b
end end
@ -13,65 +13,9 @@ class DispatcherTest < Test::Unit::TestCase
def setup def setup
Foo.a, Foo.b = 0, 0 Foo.a, Foo.b = 0, 0
ActionDispatch::Callbacks.reset_callbacks(:prepare)
ActionDispatch::Callbacks.reset_callbacks(:call) ActionDispatch::Callbacks.reset_callbacks(:call)
end end
def test_prepare_callbacks_with_cache_classes
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_prepare_callbacks_without_cache_classes
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(false)
assert_equal 1, a
assert_equal 2, b
assert_equal 3, c
# Make sure they are run again
a = b = c = nil
dispatch(false)
assert_equal 1, a
assert_equal 2, b
assert_equal 3, 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 def test_before_and_after_callbacks
ActionDispatch::Callbacks.before { |*args| Foo.a += 1; Foo.b += 1 } ActionDispatch::Callbacks.before { |*args| Foo.a += 1; Foo.b += 1 }
ActionDispatch::Callbacks.after { |*args| Foo.a += 1; Foo.b += 1 } ActionDispatch::Callbacks.after { |*args| Foo.a += 1; Foo.b += 1 }
@ -85,10 +29,20 @@ class DispatcherTest < Test::Unit::TestCase
assert_equal 4, Foo.b assert_equal 4, Foo.b
end end
def test_to_prepare_deprecation
prepared = false
assert_deprecated do
ActionDispatch::Callbacks.to_prepare { prepared = true }
end
ActionDispatch::Reloader.prepare!
assert prepared
end
private private
def dispatch(cache_classes = true, &block) def dispatch(&block)
@dispatcher ||= ActionDispatch::Callbacks.new(block || DummyApp.new, !cache_classes) @dispatcher ||= ActionDispatch::Callbacks.new(block || DummyApp.new)
@dispatcher.call({'rack.input' => StringIO.new('')}) @dispatcher.call({'rack.input' => StringIO.new('')})
end end

View File

@ -82,7 +82,7 @@ module ActiveRecord
ActiveSupport.on_load(:active_record) do ActiveSupport.on_load(:active_record) do
instantiate_observers instantiate_observers
ActionDispatch::Callbacks.to_prepare(:activerecord_instantiate_observers) do ActionDispatch::Reloader.to_prepare(:activerecord_instantiate_observers) do
ActiveRecord::Base.instantiate_observers ActiveRecord::Base.instantiate_observers
end end
end end

View File

@ -8,7 +8,7 @@ module ActiveSupport
# I18n.reload! # I18n.reload!
# end # end
# #
# ActionDispatch::Callbacks.to_prepare do # ActionDispatch::Reloader.to_prepare do
# i18n_reloader.execute_if_updated # i18n_reloader.execute_if_updated
# end # end
# #

View File

@ -19,7 +19,7 @@ module I18n
# on to_prepare callbacks. This will only happen on the config.after_initialize # on to_prepare callbacks. This will only happen on the config.after_initialize
# callback below. # callback below.
initializer "i18n.callbacks" do initializer "i18n.callbacks" do
ActionDispatch::Callbacks.to_prepare do ActionDispatch::Reloader.to_prepare do
I18n::Railtie.reloader.execute_if_updated I18n::Railtie.reloader.execute_if_updated
end end
end end

View File

@ -157,7 +157,7 @@ module Rails
middleware.use ::ActionDispatch::RemoteIp, config.action_dispatch.ip_spoofing_check, config.action_dispatch.trusted_proxies middleware.use ::ActionDispatch::RemoteIp, config.action_dispatch.ip_spoofing_check, config.action_dispatch.trusted_proxies
middleware.use ::Rack::Sendfile, config.action_dispatch.x_sendfile_header middleware.use ::Rack::Sendfile, config.action_dispatch.x_sendfile_header
middleware.use ::ActionDispatch::Reloader unless config.cache_classes middleware.use ::ActionDispatch::Reloader unless config.cache_classes
middleware.use ::ActionDispatch::Callbacks, !config.cache_classes middleware.use ::ActionDispatch::Callbacks
middleware.use ::ActionDispatch::Cookies middleware.use ::ActionDispatch::Cookies
if config.session_store if config.session_store

View File

@ -21,7 +21,7 @@ module Rails
initializer :add_to_prepare_blocks do initializer :add_to_prepare_blocks do
config.to_prepare_blocks.each do |block| config.to_prepare_blocks.each do |block|
ActionDispatch::Callbacks.to_prepare(&block) ActionDispatch::Reloader.to_prepare(&block)
end end
end end
@ -37,6 +37,10 @@ module Rails
build_middleware_stack build_middleware_stack
end end
initializer :run_prepare_callbacks do
ActionDispatch::Reloader.prepare!
end
initializer :eager_load! do initializer :eager_load! do
if config.cache_classes && !$rails_rake_task if config.cache_classes && !$rails_rake_task
ActiveSupport.run_load_hooks(:before_eager_load, self) ActiveSupport.run_load_hooks(:before_eager_load, self)
@ -52,7 +56,7 @@ module Rails
initializer :set_routes_reloader do |app| initializer :set_routes_reloader do |app|
reloader = lambda { app.routes_reloader.execute_if_updated } reloader = lambda { app.routes_reloader.execute_if_updated }
reloader.call reloader.call
ActionDispatch::Callbacks.to_prepare(&reloader) ActionDispatch::Reloader.to_prepare(&reloader)
end end
# Disable dependency loading during request cycle # Disable dependency loading during request cycle

View File

@ -26,7 +26,6 @@ end
# reloads the environment # reloads the environment
def reload!(print=true) def reload!(print=true)
puts "Reloading..." if print puts "Reloading..." if print
# This triggers the to_prepare callbacks ActionDispatch::Reloader.reload!
ActionDispatch::Callbacks.new(Proc.new {}, false).call({})
true true
end end

View File

@ -26,14 +26,14 @@ class ConsoleTest < Test::Unit::TestCase
assert_instance_of ActionDispatch::Integration::Session, session assert_instance_of ActionDispatch::Integration::Session, session
end end
def test_reload_should_fire_preparation_callbacks def test_reload_should_fire_preparation_and_cleanup_callbacks
load_environment load_environment
a = b = c = nil a = b = c = nil
# TODO: These should be defined on the initializer # TODO: These should be defined on the initializer
ActionDispatch::Callbacks.to_prepare { a = b = c = 1 } ActionDispatch::Reloader.to_prepare { a = b = c = 1 }
ActionDispatch::Callbacks.to_prepare { b = c = 2 } ActionDispatch::Reloader.to_prepare { b = c = 2 }
ActionDispatch::Callbacks.to_prepare { c = 3 } ActionDispatch::Reloader.to_cleanup { c = 3 }
# Hide Reloading... output # Hide Reloading... output
silence_stream(STDOUT) { reload! } silence_stream(STDOUT) { reload! }