mirror of
https://github.com/rails/rails.git
synced 2022-11-09 12:12:34 -05:00
Move development mode reloading up the stack to avoid issues with class reloading in middleware
This commit is contained in:
parent
53fe301a42
commit
69c049f5ab
6 changed files with 52 additions and 22 deletions
|
@ -59,6 +59,7 @@ module ActionController
|
|||
autoload :ParamsParser, 'action_controller/params_parser'
|
||||
autoload :PolymorphicRoutes, 'action_controller/polymorphic_routes'
|
||||
autoload :RecordIdentifier, 'action_controller/record_identifier'
|
||||
autoload :Reloader, 'action_controller/reloader'
|
||||
autoload :Request, 'action_controller/request'
|
||||
autoload :RequestForgeryProtection, 'action_controller/request_forgery_protection'
|
||||
autoload :Rescue, 'action_controller/rescue'
|
||||
|
|
|
@ -5,8 +5,9 @@ module ActionController
|
|||
class << self
|
||||
def define_dispatcher_callbacks(cache_classes)
|
||||
unless cache_classes
|
||||
# Development mode callbacks
|
||||
before_dispatch :reload_application
|
||||
unless self.middleware.include?(Reloader)
|
||||
self.middleware.insert_after(Failsafe, Reloader)
|
||||
end
|
||||
|
||||
ActionView::Helpers::AssetTagHelper.cache_asset_timestamps = false
|
||||
end
|
||||
|
@ -41,6 +42,30 @@ module ActionController
|
|||
callback = ActiveSupport::Callbacks::Callback.new(:prepare_dispatch, block, :identifier => identifier)
|
||||
@prepare_dispatch_callbacks.replace_or_append!(callback)
|
||||
end
|
||||
|
||||
def run_prepare_callbacks
|
||||
if defined?(Rails) && Rails.logger
|
||||
logger = Rails.logger
|
||||
else
|
||||
logger = Logger.new($stderr)
|
||||
end
|
||||
|
||||
new(logger).send :run_callbacks, :prepare_dispatch
|
||||
end
|
||||
|
||||
def reload_application
|
||||
# Run prepare callbacks before every request in development mode
|
||||
run_prepare_callbacks
|
||||
|
||||
Routing::Routes.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
|
||||
end
|
||||
|
||||
cattr_accessor :middleware
|
||||
|
@ -87,18 +112,6 @@ module ActionController
|
|||
dispatch
|
||||
end
|
||||
|
||||
def reload_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)
|
||||
|
||||
# Run prepare callbacks before every request in development mode
|
||||
run_callbacks :prepare_dispatch
|
||||
|
||||
Routing::Routes.reload
|
||||
end
|
||||
|
||||
def flush_logger
|
||||
Base.logger.flush
|
||||
end
|
||||
|
|
14
actionpack/lib/action_controller/reloader.rb
Normal file
14
actionpack/lib/action_controller/reloader.rb
Normal file
|
@ -0,0 +1,14 @@
|
|||
module ActionController
|
||||
class Reloader
|
||||
def initialize(app)
|
||||
@app = app
|
||||
end
|
||||
|
||||
def call(env)
|
||||
Dispatcher.reload_application
|
||||
@app.call(env)
|
||||
ensure
|
||||
Dispatcher.cleanup_application
|
||||
end
|
||||
end
|
||||
end
|
|
@ -6,14 +6,17 @@ class DispatcherTest < Test::Unit::TestCase
|
|||
def setup
|
||||
ENV['REQUEST_METHOD'] = 'GET'
|
||||
|
||||
Dispatcher.middleware = ActionController::MiddlewareStack.new do |middleware|
|
||||
middlewares = File.expand_path(File.join(File.dirname(__FILE__), "../../lib/action_controller/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)
|
||||
|
||||
Dispatcher.stubs(:require_dependency)
|
||||
|
||||
@dispatcher = Dispatcher.new
|
||||
end
|
||||
|
||||
def teardown
|
||||
|
@ -65,7 +68,7 @@ class DispatcherTest < Test::Unit::TestCase
|
|||
assert_nil a || b || c
|
||||
|
||||
# Run callbacks
|
||||
@dispatcher.send :run_callbacks, :prepare_dispatch
|
||||
Dispatcher.run_prepare_callbacks
|
||||
|
||||
assert_equal 1, a
|
||||
assert_equal 2, b
|
||||
|
@ -82,7 +85,7 @@ class DispatcherTest < Test::Unit::TestCase
|
|||
Dispatcher.to_prepare(:unique_id) { |*args| a = b = 1 }
|
||||
Dispatcher.to_prepare(:unique_id) { |*args| a = 2 }
|
||||
|
||||
@dispatcher.send :run_callbacks, :prepare_dispatch
|
||||
Dispatcher.run_prepare_callbacks
|
||||
assert_equal 2, a
|
||||
assert_equal nil, b
|
||||
end
|
||||
|
@ -91,7 +94,7 @@ class DispatcherTest < Test::Unit::TestCase
|
|||
def dispatch(cache_classes = true)
|
||||
ActionController::Routing::RouteSet.any_instance.stubs(:call).returns([200, {}, 'response'])
|
||||
Dispatcher.define_dispatcher_callbacks(cache_classes)
|
||||
@dispatcher.call({})
|
||||
Dispatcher.new.call({})
|
||||
end
|
||||
|
||||
def assert_subclasses(howmany, klass, message = klass.subclasses.inspect)
|
||||
|
|
|
@ -24,7 +24,6 @@ end
|
|||
#reloads the environment
|
||||
def reload!
|
||||
puts "Reloading..."
|
||||
dispatcher = ActionController::Dispatcher.new($stdout)
|
||||
dispatcher.reload_application
|
||||
Dispatcher.reload_application
|
||||
true
|
||||
end
|
||||
|
|
|
@ -583,7 +583,7 @@ 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.new(Rails.logger).send :run_callbacks, :prepare_dispatch
|
||||
Dispatcher.run_prepare_callbacks
|
||||
end
|
||||
|
||||
def disable_dependency_loading
|
||||
|
|
Loading…
Reference in a new issue