aboutsummaryrefslogtreecommitdiffstats
path: root/railties
diff options
context:
space:
mode:
Diffstat (limited to 'railties')
-rw-r--r--railties/lib/rails/application.rb6
-rw-r--r--railties/lib/rails/application/default_middleware_stack.rb22
-rw-r--r--railties/lib/rails/application/finisher.rb73
-rw-r--r--railties/lib/rails/commands/server.rb2
-rw-r--r--railties/lib/rails/console/app.rb3
-rw-r--r--railties/lib/rails/generators/rails/app/templates/config.ru (renamed from railties/lib/rails/generators/rails/app/templates/config.ru.tt)6
-rw-r--r--railties/test/application/console_test.rb11
-rw-r--r--railties/test/application/middleware_test.rb26
-rw-r--r--railties/test/generators/app_generator_test.rb2
9 files changed, 79 insertions, 72 deletions
diff --git a/railties/lib/rails/application.rb b/railties/lib/rails/application.rb
index bff33ff42e..d05d610ee1 100644
--- a/railties/lib/rails/application.rb
+++ b/railties/lib/rails/application.rb
@@ -113,7 +113,7 @@ module Rails
attr_accessor :assets, :sandbox
alias_method :sandbox?, :sandbox
- attr_reader :reloaders
+ attr_reader :reloaders, :reloader, :executor
delegate :default_url_options, :default_url_options=, to: :routes
@@ -131,6 +131,10 @@ module Rails
@message_verifiers = {}
@ran_load_hooks = false
+ @executor = Class.new(ActiveSupport::Executor)
+ @reloader = Class.new(ActiveSupport::Reloader)
+ @reloader.executor = @executor
+
# are these actually used?
@initial_variable_values = initial_variable_values
@block = block
diff --git a/railties/lib/rails/application/default_middleware_stack.rb b/railties/lib/rails/application/default_middleware_stack.rb
index 4f1cc0703d..381e548730 100644
--- a/railties/lib/rails/application/default_middleware_stack.rb
+++ b/railties/lib/rails/application/default_middleware_stack.rb
@@ -34,22 +34,10 @@ module Rails
# handling: presumably their code is not threadsafe
middleware.use ::Rack::Lock
-
- elsif config.allow_concurrency == :unsafe
- # Do nothing, even if we know this is dangerous. This is the
- # historical behaviour for true.
-
- else
- # Default concurrency setting: enabled, but safe
-
- unless config.cache_classes && config.eager_load
- # Without cache_classes + eager_load, the load interlock
- # is required for proper operation
-
- middleware.use ::ActionDispatch::LoadInterlock
- end
end
+ middleware.use ::ActionDispatch::Executor, app.executor
+
middleware.use ::Rack::Runtime
middleware.use ::Rack::MethodOverride unless config.api_only
middleware.use ::ActionDispatch::RequestId
@@ -61,7 +49,7 @@ module Rails
middleware.use ::ActionDispatch::RemoteIp, config.action_dispatch.ip_spoofing_check, config.action_dispatch.trusted_proxies
unless config.cache_classes
- middleware.use ::ActionDispatch::Reloader, lambda { reload_dependencies? }
+ middleware.use ::ActionDispatch::Reloader, app.reloader
end
middleware.use ::ActionDispatch::Callbacks
@@ -83,10 +71,6 @@ module Rails
private
- def reload_dependencies?
- config.reload_classes_only_on_change != true || app.reloaders.map(&:updated?).any?
- end
-
def load_rack_cache
rack_cache = config.action_dispatch.rack_cache
return unless rack_cache
diff --git a/railties/lib/rails/application/finisher.rb b/railties/lib/rails/application/finisher.rb
index 64ec539564..34f2265108 100644
--- a/railties/lib/rails/application/finisher.rb
+++ b/railties/lib/rails/application/finisher.rb
@@ -38,16 +38,16 @@ module Rails
app.routes.define_mounted_helper(:main_app)
end
- initializer :add_to_prepare_blocks do
+ initializer :add_to_prepare_blocks do |app|
config.to_prepare_blocks.each do |block|
- ActionDispatch::Reloader.to_prepare(&block)
+ app.reloader.to_prepare(&block)
end
end
# This needs to happen before eager load so it happens
# in exactly the same point regardless of config.cache_classes
- initializer :run_prepare_callbacks do
- ActionDispatch::Reloader.prepare!
+ initializer :run_prepare_callbacks do |app|
+ app.reloader.prepare!
end
initializer :eager_load! do
@@ -62,13 +62,47 @@ module Rails
ActiveSupport.run_load_hooks(:after_initialize, self)
end
+ initializer :configure_executor_for_concurrency do |app|
+ if config.allow_concurrency == false
+ # User has explicitly opted out of concurrent request
+ # handling: presumably their code is not threadsafe
+
+ mutex = Mutex.new
+ app.executor.to_run(prepend: true) do
+ mutex.lock
+ end
+ app.executor.to_complete(:after) do
+ mutex.unlock
+ end
+
+ elsif config.allow_concurrency == :unsafe
+ # Do nothing, even if we know this is dangerous. This is the
+ # historical behaviour for true.
+
+ else
+ # Default concurrency setting: enabled, but safe
+
+ unless config.cache_classes && config.eager_load
+ # Without cache_classes + eager_load, the load interlock
+ # is required for proper operation
+
+ app.executor.to_run(prepend: true) do
+ ActiveSupport::Dependencies.interlock.start_running
+ end
+ app.executor.to_complete(:after) do
+ ActiveSupport::Dependencies.interlock.done_running
+ end
+ end
+ end
+ end
+
# Set routes reload after the finisher hook to ensure routes added in
# the hook are taken into account.
- initializer :set_routes_reloader_hook do
+ initializer :set_routes_reloader_hook do |app|
reloader = routes_reloader
reloader.execute_if_updated
self.reloaders << reloader
- ActionDispatch::Reloader.to_prepare do
+ app.reloader.to_run do
# We configure #execute rather than #execute_if_updated because if
# autoloaded constants are cleared we need to reload routes also in
# case any was used there, as in
@@ -78,18 +112,27 @@ module Rails
# This means routes are also reloaded if i18n is updated, which
# might not be necessary, but in order to be more precise we need
# some sort of reloaders dependency support, to be added.
+ require_unload_lock!
reloader.execute
end
end
# Set clearing dependencies after the finisher hook to ensure paths
# added in the hook are taken into account.
- initializer :set_clear_dependencies_hook, group: :all do
+ initializer :set_clear_dependencies_hook, group: :all do |app|
callback = lambda do
- ActiveSupport::Dependencies.interlock.unloading do
- ActiveSupport::DescendantsTracker.clear
- ActiveSupport::Dependencies.clear
+ ActiveSupport::DescendantsTracker.clear
+ ActiveSupport::Dependencies.clear
+ end
+
+ if config.cache_classes
+ app.reloader.check = lambda { false }
+ elsif config.reload_classes_only_on_change
+ app.reloader.check = lambda do
+ app.reloaders.map(&:updated?).any?
end
+ else
+ app.reloader.check = lambda { true }
end
if config.reload_classes_only_on_change
@@ -99,15 +142,19 @@ module Rails
# Prepend this callback to have autoloaded constants cleared before
# any other possible reloading, in case they need to autoload fresh
# constants.
- ActionDispatch::Reloader.to_prepare(prepend: true) do
+ app.reloader.to_run(prepend: true) do
# In addition to changes detected by the file watcher, if routes
# or i18n have been updated we also need to clear constants,
# that's why we run #execute rather than #execute_if_updated, this
# callback has to clear autoloaded constants after any update.
- reloader.execute
+ class_unload! do
+ reloader.execute
+ end
end
else
- ActionDispatch::Reloader.to_cleanup(&callback)
+ app.reloader.to_complete do
+ class_unload!(&callback)
+ end
end
end
diff --git a/railties/lib/rails/commands/server.rb b/railties/lib/rails/commands/server.rb
index 27cbaf360a..d7597a13e1 100644
--- a/railties/lib/rails/commands/server.rb
+++ b/railties/lib/rails/commands/server.rb
@@ -114,8 +114,6 @@ module Rails
puts "=> Booting #{ActiveSupport::Inflector.demodulize(server)}"
puts "=> Rails #{Rails.version} application starting in #{Rails.env} on #{url}"
puts "=> Run `rails server -h` for more startup options"
-
- puts "=> Ctrl-C to shutdown server" unless options[:daemonize]
end
def create_cache_file
diff --git a/railties/lib/rails/console/app.rb b/railties/lib/rails/console/app.rb
index ac5836a588..9ad77e0a80 100644
--- a/railties/lib/rails/console/app.rb
+++ b/railties/lib/rails/console/app.rb
@@ -29,8 +29,7 @@ module Rails
# reloads the environment
def reload!(print=true)
puts "Reloading..." if print
- ActionDispatch::Reloader.cleanup!
- ActionDispatch::Reloader.prepare!
+ Rails.application.reloader.reload!
true
end
end
diff --git a/railties/lib/rails/generators/rails/app/templates/config.ru.tt b/railties/lib/rails/generators/rails/app/templates/config.ru
index 343c0833d7..bd83b25412 100644
--- a/railties/lib/rails/generators/rails/app/templates/config.ru.tt
+++ b/railties/lib/rails/generators/rails/app/templates/config.ru
@@ -1,10 +1,4 @@
# This file is used by Rack-based servers to start the application.
require ::File.expand_path('../config/environment', __FILE__)
-<%- unless options[:skip_action_cable] -%>
-
-# Action Cable requires that all classes are loaded in advance
-Rails.application.eager_load!
-<%- end -%>
-
run Rails.application
diff --git a/railties/test/application/console_test.rb b/railties/test/application/console_test.rb
index 7bf123d12b..ea68e63f8f 100644
--- a/railties/test/application/console_test.rb
+++ b/railties/test/application/console_test.rb
@@ -52,12 +52,11 @@ class ConsoleTest < ActiveSupport::TestCase
a = b = c = nil
# TODO: These should be defined on the initializer
- ActionDispatch::Reloader.to_cleanup { a = b = c = 1 }
- ActionDispatch::Reloader.to_cleanup { b = c = 2 }
- ActionDispatch::Reloader.to_prepare { c = 3 }
+ ActiveSupport::Reloader.to_complete { a = b = c = 1 }
+ ActiveSupport::Reloader.to_complete { b = c = 2 }
+ ActiveSupport::Reloader.to_prepare { c = 3 }
- # Hide Reloading... output
- silence_stream(STDOUT) { irb_context.reload! }
+ irb_context.reload!(false)
assert_equal 1, a
assert_equal 2, b
@@ -81,7 +80,7 @@ class ConsoleTest < ActiveSupport::TestCase
MODEL
assert !User.new.respond_to?(:age)
- silence_stream(STDOUT) { irb_context.reload! }
+ irb_context.reload!(false)
assert User.new.respond_to?(:age)
end
diff --git a/railties/test/application/middleware_test.rb b/railties/test/application/middleware_test.rb
index 1434522cce..5869ff64bc 100644
--- a/railties/test/application/middleware_test.rb
+++ b/railties/test/application/middleware_test.rb
@@ -26,7 +26,7 @@ module ApplicationTests
assert_equal [
"Rack::Sendfile",
"ActionDispatch::Static",
- "ActionDispatch::LoadInterlock",
+ "ActionDispatch::Executor",
"ActiveSupport::Cache::Strategy::LocalCache",
"Rack::Runtime",
"Rack::MethodOverride",
@@ -38,8 +38,6 @@ module ApplicationTests
"ActionDispatch::Reloader",
"ActionDispatch::Callbacks",
"ActiveRecord::Migration::CheckPending",
- "ActiveRecord::ConnectionAdapters::ConnectionManagement",
- "ActiveRecord::QueryCache",
"ActionDispatch::Cookies",
"ActionDispatch::Session::CookieStore",
"ActionDispatch::Flash",
@@ -57,7 +55,7 @@ module ApplicationTests
assert_equal [
"Rack::Sendfile",
"ActionDispatch::Static",
- "ActionDispatch::LoadInterlock",
+ "ActionDispatch::Executor",
"ActiveSupport::Cache::Strategy::LocalCache",
"Rack::Runtime",
"ActionDispatch::RequestId",
@@ -67,8 +65,6 @@ module ApplicationTests
"ActionDispatch::RemoteIp",
"ActionDispatch::Reloader",
"ActionDispatch::Callbacks",
- "ActiveRecord::ConnectionAdapters::ConnectionManagement",
- "ActiveRecord::QueryCache",
"Rack::Head",
"Rack::ConditionalGet",
"Rack::ETag"
@@ -114,23 +110,12 @@ module ApplicationTests
test "removing Active Record omits its middleware" do
use_frameworks []
boot!
- assert !middleware.include?("ActiveRecord::ConnectionAdapters::ConnectionManagement")
- assert !middleware.include?("ActiveRecord::QueryCache")
assert !middleware.include?("ActiveRecord::Migration::CheckPending")
end
- test "includes interlock if cache_classes is set but eager_load is not" do
- add_to_config "config.cache_classes = true"
- boot!
- assert_not_includes middleware, "Rack::Lock"
- assert_includes middleware, "ActionDispatch::LoadInterlock"
- end
-
- test "includes interlock if cache_classes is off" do
- add_to_config "config.cache_classes = false"
+ test "includes executor" do
boot!
- assert_not_includes middleware, "Rack::Lock"
- assert_includes middleware, "ActionDispatch::LoadInterlock"
+ assert_includes middleware, "ActionDispatch::Executor"
end
test "does not include lock if cache_classes is set and so is eager_load" do
@@ -138,21 +123,18 @@ module ApplicationTests
add_to_config "config.eager_load = true"
boot!
assert_not_includes middleware, "Rack::Lock"
- assert_not_includes middleware, "ActionDispatch::LoadInterlock"
end
test "does not include lock if allow_concurrency is set to :unsafe" do
add_to_config "config.allow_concurrency = :unsafe"
boot!
assert_not_includes middleware, "Rack::Lock"
- assert_not_includes middleware, "ActionDispatch::LoadInterlock"
end
test "includes lock if allow_concurrency is disabled" do
add_to_config "config.allow_concurrency = false"
boot!
assert_includes middleware, "Rack::Lock"
- assert_not_includes middleware, "ActionDispatch::LoadInterlock"
end
test "removes static asset server if public_file_server.enabled is disabled" do
diff --git a/railties/test/generators/app_generator_test.rb b/railties/test/generators/app_generator_test.rb
index a86f190bb2..20b2cd3cca 100644
--- a/railties/test/generators/app_generator_test.rb
+++ b/railties/test/generators/app_generator_test.rb
@@ -670,7 +670,7 @@ class AppGeneratorTest < Rails::Generators::TestCase
def test_spring_no_fork
jruby_skip "spring doesn't run on JRuby"
- assert_called_with(Process, :respond_to?, [:fork], returns: false) do
+ assert_called_with(Process, :respond_to?, [[:fork], [:fork]], returns: false) do
run_generator
assert_file "Gemfile" do |content|