diff options
author | José Valim <jose.valim@gmail.com> | 2012-08-01 15:07:01 +0200 |
---|---|---|
committer | José Valim <jose.valim@gmail.com> | 2012-08-21 14:46:12 -0300 |
commit | e6747d87f3a061d153215715d56acbb0be20191f (patch) | |
tree | 7466bf0ceff18642e3e1d154419b05d6414e2be0 /railties | |
parent | df1a5e492ae178856f6cf92ae70ce620f4cd0613 (diff) | |
download | rails-e6747d87f3a061d153215715d56acbb0be20191f.tar.gz rails-e6747d87f3a061d153215715d56acbb0be20191f.tar.bz2 rails-e6747d87f3a061d153215715d56acbb0be20191f.zip |
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.
Diffstat (limited to 'railties')
9 files changed, 67 insertions, 8 deletions
diff --git a/railties/lib/rails/application.rb b/railties/lib/rails/application.rb index 3531728421..9f624437e5 100644 --- a/railties/lib/rails/application.rb +++ b/railties/lib/rails/application.rb @@ -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 diff --git a/railties/lib/rails/application/bootstrap.rb b/railties/lib/rails/application/bootstrap.rb index e567df7162..1e5f95336f 100644 --- a/railties/lib/rails/application/bootstrap.rb +++ b/railties/lib/rails/application/bootstrap.rb @@ -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 diff --git a/railties/lib/rails/application/configuration.rb b/railties/lib/rails/application/configuration.rb index 2b36cc9d0d..7dffe91bb9 100644 --- a/railties/lib/rails/application/configuration.rb +++ b/railties/lib/rails/application/configuration.rb @@ -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 diff --git a/railties/lib/rails/application/finisher.rb b/railties/lib/rails/application/finisher.rb index 60aa40b92f..ba9f501546 100644 --- a/railties/lib/rails/application/finisher.rb +++ b/railties/lib/rails/application/finisher.rb @@ -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 diff --git a/railties/lib/rails/generators/rails/app/templates/config/environments/development.rb.tt b/railties/lib/rails/generators/rails/app/templates/config/environments/development.rb.tt index 2016eb8b05..122e7e2b34 100644 --- a/railties/lib/rails/generators/rails/app/templates/config/environments/development.rb.tt +++ b/railties/lib/rails/generators/rails/app/templates/config/environments/development.rb.tt @@ -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 diff --git a/railties/lib/rails/generators/rails/app/templates/config/environments/production.rb.tt b/railties/lib/rails/generators/rails/app/templates/config/environments/production.rb.tt index 80413be0d3..a627636089 100644 --- a/railties/lib/rails/generators/rails/app/templates/config/environments/production.rb.tt +++ b/railties/lib/rails/generators/rails/app/templates/config/environments/production.rb.tt @@ -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 diff --git a/railties/lib/rails/generators/rails/app/templates/config/environments/test.rb.tt b/railties/lib/rails/generators/rails/app/templates/config/environments/test.rb.tt index 878deb49d7..8ab27eb6e1 100644 --- a/railties/lib/rails/generators/rails/app/templates/config/environments/test.rb.tt +++ b/railties/lib/rails/generators/rails/app/templates/config/environments/test.rb.tt @@ -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" diff --git a/railties/test/application/rake_test.rb b/railties/test/application/rake_test.rb index a450f90dbf..5d7fa7e397 100644 --- a/railties/test/application/rake_test.rb +++ b/railties/test/application/rake_test.rb @@ -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` } diff --git a/railties/test/isolation/abstract_unit.rb b/railties/test/isolation/abstract_unit.rb index 8f04692aef..d89cfba56d 100644 --- a/railties/test/isolation/abstract_unit.rb +++ b/railties/test/isolation/abstract_unit.rb @@ -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 |