mirror of
https://github.com/rails/rails.git
synced 2022-11-09 12:12:34 -05:00
Allow users to choose when to eager_load the application or not.
Previously, the eager load behavior was mostly coupled to config.cache_classes, however this was suboptimal since in some environments a developer may want to cache classes but not necessarily load them all on boot (for example, test env). This pull request also promotes the use of config.eager_load set to true by default in production. In the majority of the cases, this is the behavior you want since it will copy most of your app into memory on boot (which was also the previous behavior). Finally, this fix a long standing Rails bug where it was impossible to access a model in a rake task when Rails was set as thread safe.
This commit is contained in:
parent
df1a5e492a
commit
e6747d87f3
9 changed files with 67 additions and 8 deletions
|
@ -83,6 +83,13 @@ module Rails
|
|||
@queue = nil
|
||||
end
|
||||
|
||||
# Eager load all dependencies before eager loading
|
||||
# the application.
|
||||
def eager_load!
|
||||
railties.each(&:eager_load!)
|
||||
super
|
||||
end
|
||||
|
||||
# Returns true if the application is initialized.
|
||||
def initialized?
|
||||
@initialized
|
||||
|
@ -216,8 +223,9 @@ module Rails
|
|||
railties.each { |r| r.run_tasks_blocks(app) }
|
||||
super
|
||||
require "rails/tasks"
|
||||
config = self.config
|
||||
task :environment do
|
||||
$rails_rake_task = true
|
||||
config.eager_load = false
|
||||
require_environment!
|
||||
end
|
||||
end
|
||||
|
|
|
@ -13,6 +13,20 @@ module Rails
|
|||
require "active_support/all" unless config.active_support.bare
|
||||
end
|
||||
|
||||
initializer :set_eager_load, :group => :all do
|
||||
if config.eager_load.nil?
|
||||
warn <<-INFO
|
||||
config.eager_load is set to nil. Please update your config/environments file accordingly:
|
||||
|
||||
* development - set it to false
|
||||
* test - set it to false (unless you use a tool that preloads your test environment)
|
||||
* production - set it to true
|
||||
|
||||
INFO
|
||||
config.eager_load = config.cache_classes
|
||||
end
|
||||
end
|
||||
|
||||
# Preload all frameworks specified by the Configuration#frameworks.
|
||||
# Used by Passenger to ensure everything's loaded before forking and
|
||||
# to avoid autoload race conditions in JRuby.
|
||||
|
@ -60,7 +74,6 @@ module Rails
|
|||
end
|
||||
|
||||
# Sets the dependency loading mechanism.
|
||||
# TODO: Remove files from the $" and always use require.
|
||||
initializer :initialize_dependency_mechanism, :group => :all do
|
||||
ActiveSupport::Dependencies.mechanism = config.cache_classes ? :require : :load
|
||||
end
|
||||
|
|
|
@ -7,7 +7,7 @@ module Rails
|
|||
class Configuration < ::Rails::Engine::Configuration
|
||||
attr_accessor :allow_concurrency, :asset_host, :asset_path, :assets, :autoflush_log,
|
||||
:cache_classes, :cache_store, :consider_all_requests_local, :console,
|
||||
:dependency_loading, :exceptions_app, :file_watcher, :filter_parameters,
|
||||
:eager_load, :exceptions_app, :file_watcher, :filter_parameters,
|
||||
:force_ssl, :helpers_paths, :logger, :log_formatter, :log_tags,
|
||||
:preload_frameworks, :railties_order, :relative_url_root, :secret_token,
|
||||
:serve_static_assets, :ssl_options, :static_cache_control, :session_options,
|
||||
|
@ -24,7 +24,6 @@ module Rails
|
|||
@consider_all_requests_local = false
|
||||
@filter_parameters = []
|
||||
@helpers_paths = []
|
||||
@dependency_loading = true
|
||||
@serve_static_assets = true
|
||||
@static_cache_control = nil
|
||||
@force_ssl = false
|
||||
|
@ -45,6 +44,7 @@ module Rails
|
|||
@log_formatter = ActiveSupport::Logger::SimpleFormatter.new
|
||||
@queue = Rails::Queueing::Queue
|
||||
@queue_consumer = Rails::Queueing::ThreadedConsumer
|
||||
@eager_load = nil
|
||||
|
||||
@assets = ActiveSupport::OrderedOptions.new
|
||||
@assets.enabled = false
|
||||
|
@ -98,7 +98,7 @@ module Rails
|
|||
def threadsafe!
|
||||
@preload_frameworks = true
|
||||
@cache_classes = true
|
||||
@dependency_loading = false
|
||||
@eager_load = true
|
||||
@allow_concurrency = true
|
||||
self
|
||||
end
|
||||
|
|
|
@ -50,7 +50,7 @@ module Rails
|
|||
end
|
||||
|
||||
initializer :eager_load! do
|
||||
if config.cache_classes && !(defined?($rails_rake_task) && $rails_rake_task)
|
||||
if config.eager_load
|
||||
ActiveSupport.run_load_hooks(:before_eager_load, self)
|
||||
eager_load!
|
||||
end
|
||||
|
@ -91,7 +91,7 @@ module Rails
|
|||
|
||||
# Disable dependency loading during request cycle
|
||||
initializer :disable_dependency_loading do
|
||||
if config.cache_classes && !config.dependency_loading
|
||||
if config.eager_load
|
||||
ActiveSupport::Dependencies.unhook!
|
||||
end
|
||||
end
|
||||
|
|
|
@ -6,6 +6,9 @@
|
|||
# since you don't have to restart the web server when you make code changes.
|
||||
config.cache_classes = false
|
||||
|
||||
# Do not eager load code on boot.
|
||||
config.eager_load = false
|
||||
|
||||
# Show full error reports and disable caching.
|
||||
config.consider_all_requests_local = true
|
||||
config.action_controller.perform_caching = false
|
||||
|
|
|
@ -4,6 +4,12 @@
|
|||
# Code is not reloaded between requests.
|
||||
config.cache_classes = true
|
||||
|
||||
# Eager load code on boot. This eager loads most of Rails and
|
||||
# your application in memory, allowing both thread web servers
|
||||
# and those relying on copy on write to perform better.
|
||||
# Rake tasks automatically ignore this option for performance.
|
||||
config.eager_load = true
|
||||
|
||||
# Full error reports are disabled and caching is turned on.
|
||||
config.consider_all_requests_local = false
|
||||
config.action_controller.perform_caching = true
|
||||
|
|
|
@ -7,6 +7,11 @@
|
|||
# and recreated between test runs. Don't rely on the data there!
|
||||
config.cache_classes = true
|
||||
|
||||
# Do not eager load code on boot. This avoids loading your whole application
|
||||
# just for the purpose of running a single test. If you are using a tool that
|
||||
# preloads Rails for running tests, you may have to set it to true.
|
||||
config.eager_load = false
|
||||
|
||||
# Configure static asset server for tests with Cache-Control for performance.
|
||||
config.serve_static_assets = true
|
||||
config.static_cache_control = "public, max-age=3600"
|
||||
|
|
|
@ -55,6 +55,30 @@ module ApplicationTests
|
|||
assert_match "Doing something...", output
|
||||
end
|
||||
|
||||
def test_does_not_explode_when_accessing_a_model_with_eager_load
|
||||
add_to_config <<-RUBY
|
||||
config.eager_load = true
|
||||
|
||||
rake_tasks do
|
||||
task :do_nothing => :environment do
|
||||
Hello.new.world
|
||||
end
|
||||
end
|
||||
RUBY
|
||||
|
||||
app_file "app/models/hello.rb", <<-RUBY
|
||||
class Hello
|
||||
def world
|
||||
puts "Hello world"
|
||||
end
|
||||
end
|
||||
RUBY
|
||||
|
||||
output = Dir.chdir(app_path){ `rake do_nothing` }
|
||||
puts output
|
||||
assert_match "Hello world", output
|
||||
end
|
||||
|
||||
def test_code_statistics_sanity
|
||||
assert_match "Code LOC: 5 Test LOC: 0 Code to Test Ratio: 1:0.0",
|
||||
Dir.chdir(app_path){ `rake stats` }
|
||||
|
|
|
@ -12,7 +12,6 @@ require 'bundler/setup'
|
|||
require 'minitest/autorun'
|
||||
require 'active_support/test_case'
|
||||
|
||||
# TODO: Remove setting this magic constant
|
||||
RAILS_FRAMEWORK_ROOT = File.expand_path("#{File.dirname(__FILE__)}/../../..")
|
||||
|
||||
# These files do not require any others and are needed
|
||||
|
@ -118,6 +117,7 @@ module TestHelpers
|
|||
end
|
||||
|
||||
add_to_config <<-RUBY
|
||||
config.eager_load = false
|
||||
config.secret_token = "3b7cd727ee24e8444053437c36cc66c4"
|
||||
config.session_store :cookie_store, :key => "_myapp_session"
|
||||
config.active_support.deprecation = :log
|
||||
|
|
Loading…
Reference in a new issue