Extract routes reloading responsibilities from application and load them just upon a request.

This commit is contained in:
José Valim 2010-01-23 15:05:13 +01:00
parent 4eab3aad8d
commit 80130d1201
8 changed files with 80 additions and 74 deletions

View File

@ -37,7 +37,7 @@ module ActionDispatch
def initialize(app, prepare_each_request = false)
@app, @prepare_each_request = app, prepare_each_request
run_callbacks(:prepare)
run_callbacks(:prepare) unless @prepare_each_request
end
def call(env)

View File

@ -5,22 +5,14 @@ module ActionDispatch
class Railtie < Rails::Railtie
plugin_name :action_dispatch
# Initialize route files to an array
config.action_dispatch.route_files = []
# Prepare dispatcher callbacks and run 'prepare' callbacks
initializer "action_dispatch.prepare_dispatcher" do |app|
# TODO: This used to say unless defined?(Dispatcher). Find out why and fix.
require 'rails/dispatcher'
unless app.config.cache_classes
# Setup dev mode route reloading
routes_last_modified = app.routes_changed_at
reload_routes = lambda do
unless app.routes_changed_at == routes_last_modified
routes_last_modified = app.routes_changed_at
app.reload_routes!
end
end
ActionDispatch::Callbacks.before { |callbacks| reload_routes.call }
end
ActionDispatch::Callbacks.to_prepare { app.routes_reloader.reload_if_changed }
end
end
end

View File

@ -2,25 +2,20 @@ require 'fileutils'
module Rails
class Application < Engine
# TODO Clear up 2 way delegation flow between App class and instance.
# Infact just add a method_missing on the class.
#
# TODO I'd like to track the "default app" different using an inherited hook.
#
autoload :RoutesReloader, 'rails/application/routes_reloader'
# TODO Check helpers works as expected
#
# TODO Check routes namespaces
class << self
alias :configure :class_eval
delegate :initialize!, :load_tasks, :load_generators, :root, :to => :instance
private :new
alias :configure :class_eval
def instance
@instance ||= new
end
def config
@config ||= Configuration.new(original_root)
@config ||= Configuration.new(self.original_root)
end
def original_root
@ -30,53 +25,36 @@ module Rails
def inherited(base)
super
Railtie.plugins.delete(base)
Rails.application = base.instance
end
def routes
ActionController::Routing::Routes
protected
def method_missing(*args, &block)
instance.send(*args, &block)
end
end
delegate :routes, :to => :'self.class'
attr_reader :route_configuration_files
def initialize
require_environment
Rails.application ||= self
@route_configuration_files = []
end
def routes
ActionController::Routing::Routes
end
def routes_reloader
@routes_reloader ||= RoutesReloader.new(config)
end
def reload_routes!
routes_reloader.reload!
end
def initialize!
run_initializers(self)
self
end
def routes_changed_at
routes_changed_at = nil
route_configuration_files.each do |config|
config_changed_at = File.stat(config).mtime
if routes_changed_at.nil? || config_changed_at > routes_changed_at
routes_changed_at = config_changed_at
end
end
routes_changed_at
end
def reload_routes!
routes = Rails::Application.routes
routes.disable_clear_and_finalize = true
routes.clear!
route_configuration_files.each { |config| load(config) }
routes.finalize!
nil
ensure
routes.disable_clear_and_finalize = false
end
def require_environment
environment = config.paths.config.environment.to_a.first
@ -109,10 +87,7 @@ module Rails
end
def app
@app ||= begin
reload_routes!
middleware.build(routes)
end
@app ||= middleware.build(routes)
end
def call(env)
@ -207,7 +182,7 @@ module Rails
initializer :add_builtin_route do |app|
if Rails.env.development?
app.route_configuration_files << File.join(RAILTIES_PATH, 'builtin', 'routes.rb')
app.config.action_dispatch.route_files << File.join(RAILTIES_PATH, 'builtin', 'routes.rb')
end
end

View File

@ -0,0 +1,46 @@
module Rails
class Application
class RoutesReloader
attr_reader :config
def initialize(config)
@config, @last_change_at = config, nil
end
def changed_at
routes_changed_at = nil
config.action_dispatch.route_files.each do |config|
config_changed_at = File.stat(config).mtime
if routes_changed_at.nil? || config_changed_at > routes_changed_at
routes_changed_at = config_changed_at
end
end
routes_changed_at
end
def reload!
routes = Rails::Application.routes
routes.disable_clear_and_finalize = true
routes.clear!
config.action_dispatch.route_files.each { |config| load(config) }
routes.finalize!
nil
ensure
routes.disable_clear_and_finalize = false
end
def reload_if_changed
current_change_at = changed_at
if @last_change_at != current_change_at
@last_change_at = current_change_at
reload!
end
end
end
end
end

View File

@ -213,10 +213,7 @@ module Rails
self.preload_frameworks = true
self.cache_classes = true
self.dependency_loading = false
if respond_to?(:action_controller)
action_controller.allow_concurrency = true
end
action_controller.allow_concurrency = true if respond_to?(:action_controller)
self
end

View File

@ -26,7 +26,6 @@ end
#reloads the environment
def reload!
puts "Reloading..."
ActionDispatch::Callbacks.new(lambda {}, true)
Rails.application.reload_routes!
ActionDispatch::Callbacks.new(lambda {}, true).call({})
true
end

View File

@ -1,8 +1,6 @@
require 'active_support/core_ext/module/delegation'
module Rails
# TODO Move I18n here
# TODO Set routes namespaces
class Engine < Railtie
class << self
attr_accessor :called_from
@ -75,9 +73,9 @@ module Rails
config.load_once_paths.freeze
end
initializer :add_routing_files do |app|
initializer :add_routing_files do
config.paths.config.routes.to_a.each do |route|
app.route_configuration_files.unshift(route) if File.exists?(route)
config.action_dispatch.route_files.unshift(route) if File.exists?(route)
end
end

View File

@ -60,8 +60,7 @@ module Rails
initializer :add_routing_file, :after => :initialize_routing do |app|
routing_file = "#{path}/config/routes.rb"
if File.exist?(routing_file)
app.route_configuration_files << routing_file
app.reload_routes!
app.config.action_dispatch.route_files.unshift(routing_file)
end
end
end