Skip to content
This repository
Browse code

Get rid of config.preload_frameworks in favor of config.eager_load_na…

…mespaces

The new option allows any Ruby namespace to be registered and set
up for eager load. We are effectively exposing the structure existing
in Rails since v3.0 for all developers in order to make their applications
thread-safe and CoW friendly.
  • Loading branch information...
commit 2801786e1a51b7cf7d7c3fd72b5fc9974f83f435 1 parent a1687e4
José Valim authored August 01, 2012
5  actionmailer/lib/action_mailer.rb
@@ -35,7 +35,10 @@
35 35
 module ActionMailer
36 36
   extend ::ActiveSupport::Autoload
37 37
 
38  
-  autoload :Collector
  38
+  eager_autoload do
  39
+    autoload :Collector
  40
+  end
  41
+
39 42
   autoload :Base
40 43
   autoload :DeliveryMethods
41 44
   autoload :MailHelper
1  actionmailer/lib/action_mailer/railtie.rb
@@ -5,6 +5,7 @@
5 5
 module ActionMailer
6 6
   class Railtie < Rails::Railtie
7 7
     config.action_mailer = ActiveSupport::OrderedOptions.new
  8
+    config.eager_load_namespaces << ActionMailer
8 9
 
9 10
     initializer "action_mailer.logger" do
10 11
       ActiveSupport.on_load(:action_mailer) { self.logger ||= Rails.logger }
6  actionpack/lib/action_controller.rb
@@ -48,6 +48,12 @@ module ActionController
48 48
   eager_autoload do
49 49
     autoload :RecordIdentifier
50 50
   end
  51
+
  52
+  def self.eager_load!
  53
+    super
  54
+    ActionController::Caching.eager_load!
  55
+    HTML.eager_load!
  56
+  end
51 57
 end
52 58
 
53 59
 # All of these simply register additional autoloads
2  actionpack/lib/action_controller/railtie.rb
@@ -9,6 +9,8 @@ module ActionController
9 9
   class Railtie < Rails::Railtie #:nodoc:
10 10
     config.action_controller = ActiveSupport::OrderedOptions.new
11 11
 
  12
+    config.eager_load_namespaces << ActionController
  13
+
12 14
     initializer "action_controller.assets_config", :group => :all do |app|
13 15
       app.config.action_controller.assets_dir ||= app.config.paths["public"].first
14 16
     end
8  actionpack/lib/action_dispatch.rb
@@ -38,9 +38,11 @@ module ActionDispatch
38 38
   class IllegalStateError < StandardError
39 39
   end
40 40
 
41  
-  autoload_under 'http' do
42  
-    autoload :Request
43  
-    autoload :Response
  41
+  eager_autoload do
  42
+    autoload_under 'http' do
  43
+      autoload :Request
  44
+      autoload :Response
  45
+    end
44 46
   end
45 47
 
46 48
   autoload_under 'middleware' do
2  actionpack/lib/action_dispatch/railtie.rb
@@ -25,6 +25,8 @@ class Railtie < Rails::Railtie
25 25
       'X-Content-Type-Options' => 'nosniff'
26 26
     }
27 27
 
  28
+    config.eager_load_namespaces << ActionDispatch
  29
+
28 30
     initializer "action_dispatch.configure" do |app|
29 31
       ActionDispatch::Http::URL.tld_length = app.config.action_dispatch.tld_length
30 32
       ActionDispatch::Request.ignore_accept_header = app.config.action_dispatch.ignore_accept_header
6  actionpack/lib/action_view.rb
@@ -38,7 +38,6 @@ module ActionView
38 38
     autoload :PathSet
39 39
     autoload :Template
40 40
 
41  
-
42 41
     autoload_under "renderer" do
43 42
       autoload :Renderer
44 43
       autoload :AbstractRenderer
@@ -77,6 +76,11 @@ module ActionView
77 76
   autoload :TestCase
78 77
 
79 78
   ENCODING_FLAG = '#.*coding[:=]\s*(\S+)[ \t]*'
  79
+
  80
+  def self.eager_load!
  81
+    super
  82
+    ActionView::Template.eager_load!
  83
+  end
80 84
 end
81 85
 
82 86
 require 'active_support/core_ext/string/output_safety'
2  actionpack/lib/action_view/railtie.rb
@@ -9,6 +9,8 @@ class Railtie < Rails::Railtie
9 9
     config.action_view.javascript_expansions = { :defaults => %w(jquery jquery_ujs) }
10 10
     config.action_view.embed_authenticity_token_in_remote_forms = false
11 11
 
  12
+    config.eager_load_namespaces << ActionView
  13
+
12 14
     initializer "action_view.embed_authenticity_token_in_remote_forms" do |app|
13 15
       ActiveSupport.on_load(:action_view) do
14 16
         ActionView::Helpers::FormTagHelper.embed_authenticity_token_in_remote_forms =
16  activemodel/lib/active_model.rb
@@ -34,7 +34,6 @@ module ActiveModel
34 34
   autoload :Conversion
35 35
   autoload :Dirty
36 36
   autoload :EachValidator, 'active_model/validator'
37  
-  autoload :Errors
38 37
   autoload :Lint
39 38
   autoload :MassAssignmentSecurity
40 39
   autoload :Model
@@ -49,11 +48,22 @@ module ActiveModel
49 48
   autoload :Validations
50 49
   autoload :Validator
51 50
 
  51
+  eager_autoload do
  52
+    autoload :Errors
  53
+  end
  54
+
52 55
   module Serializers
53 56
     extend ActiveSupport::Autoload
54 57
 
55  
-    autoload :JSON
56  
-    autoload :Xml
  58
+    eager_autoload do
  59
+      autoload :JSON
  60
+      autoload :Xml
  61
+    end
  62
+  end
  63
+
  64
+  def eager_load!
  65
+    super
  66
+    ActiveModel::Serializer.eager_load!
57 67
   end
58 68
 end
59 69
 
8  activemodel/lib/active_model/railtie.rb
... ...
@@ -1,2 +1,8 @@
1 1
 require "active_model"
2  
-require "rails"
  2
+require "rails"
  3
+
  4
+module ActiveModel
  5
+  class Railtie < Rails::Railtie
  6
+    config.eager_load_namespaces << ActiveModel
  7
+  end
  8
+end
9  activerecord/lib/active_record.rb
@@ -160,6 +160,15 @@ module Tasks
160 160
 
161 161
   autoload :TestCase
162 162
   autoload :TestFixtures, 'active_record/fixtures'
  163
+
  164
+  def self.eager_load!
  165
+    super
  166
+    ActiveRecord::Locking.eager_load!
  167
+    ActiveRecord::Scoping.eager_load!
  168
+    ActiveRecord::Associations.eager_load!
  169
+    ActiveRecord::AttributeMethods.eager_load!
  170
+    ActiveRecord::ConnectionAdapters.eager_load!
  171
+  end
163 172
 end
164 173
 
165 174
 ActiveSupport.on_load(:active_record) do
3  activerecord/lib/active_record/railtie.rb
@@ -29,8 +29,11 @@ class Railtie < Rails::Railtie
29 29
       'ActiveRecord::RecordNotSaved'   => :unprocessable_entity
30 30
     )
31 31
 
  32
+
32 33
     config.active_record.use_schema_cache_dump = true
33 34
 
  35
+    config.eager_load_namespaces << ActiveRecord
  36
+
34 37
     rake_tasks do
35 38
       require "active_record/base"
36 39
       load "active_record/railties/databases.rake"
2  activesupport/lib/active_support/railtie.rb
@@ -5,6 +5,8 @@ module ActiveSupport
5 5
   class Railtie < Rails::Railtie
6 6
     config.active_support = ActiveSupport::OrderedOptions.new
7 7
 
  8
+    config.eager_load_namespaces << ActiveSupport
  9
+
8 10
     initializer "active_support.deprecation_behavior" do |app|
9 11
       if deprecation = app.config.active_support.deprecation
10 12
         ActiveSupport::Deprecation.behavior = deprecation
6  guides/source/configuring.textile
Source Rendered
@@ -107,8 +107,6 @@ end
107 107
 
108 108
 * +config.middleware+ allows you to configure the application's middleware. This is covered in depth in the "Configuring Middleware":#configuring-middleware section below.
109 109
 
110  
-* +config.preload_frameworks+ enables or disables preloading all frameworks at startup. Enabled by +config.threadsafe!+. Defaults to +nil+, so is disabled.
111  
-
112 110
 * +config.queue+ configures a different queue implementation for the application. Defaults to +Rails::Queueing::Queue+. Note that, if the default queue is changed, the default +queue_consumer+ is not going to be initialized, it is up to the new queue implementation to handle starting and shutting down its own consumer(s).
113 111
 
114 112
 * +config.queue_consumer+ configures a different consumer implementation for the default queue. Defaults to +Rails::Queueing::ThreadedConsumer+.
@@ -127,7 +125,7 @@ config.session_store :my_custom_store
127 125
 
128 126
 This custom store must be defined as +ActionDispatch::Session::MyCustomStore+. In addition to symbols, they can also be objects implementing a certain API, like +ActiveRecord::SessionStore+, in which case no special namespace is required.
129 127
 
130  
-* +config.threadsafe!+ enables +cache_classes+, +dependency_loading+, +eager_load+ and +preload_frameworks+ to make the application threadsafe.
  128
+* +config.threadsafe!+ enables +cache_classes+ and +eager_load+ to make the application threadsafe.
131 129
 
132 130
 WARNING: Threadsafe operation is incompatible with the normal workings of development mode Rails. In particular, automatic dependency loading and class reloading are automatically disabled when you call +config.threadsafe!+.
133 131
 
@@ -654,8 +652,6 @@ Serves as a placeholder so that +:load_environment_config+ can be defined to run
654 652
 
655 653
 *+load_active_support+* Requires +active_support/dependencies+ which sets up the basis for Active Support. Optionally requires +active_support/all+ if +config.active_support.bare+ is un-truthful, which is the default.
656 654
 
657  
-*+preload_frameworks+* Loads all autoload dependencies of Rails automatically if +config.preload_frameworks+ is +true+ or "truthful". By default this configuration option is disabled. In Rails, when internal classes are referenced for the first time they are autoloaded. +:preload_frameworks+ loads all of this at once on initialization.
658  
-
659 655
 *+initialize_logger+* Initializes the logger (an +ActiveSupport::BufferedLogger+ object) for the application and makes it accessible at +Rails.logger+, provided that no initializer inserted before this point has defined +Rails.logger+.
660 656
 
661 657
 *+initialize_cache+* If +Rails.cache+ isn't set yet, initializes the cache by referencing the value in +config.cache_store+ and stores the outcome as +Rails.cache+. If this object responds to the +middleware+ method, its middleware is inserted before +Rack::Runtime+ in the middleware stack.
7  railties/lib/rails/application.rb
@@ -83,13 +83,6 @@ def initialize
83 83
       @queue            = nil
84 84
     end
85 85
 
86  
-    # Eager load all dependencies before eager loading
87  
-    # the application.
88  
-    def eager_load!
89  
-      railties.each(&:eager_load!)
90  
-      super
91  
-    end
92  
-
93 86
     # Returns true if the application is initialized.
94 87
     def initialized?
95 88
       @initialized
9  railties/lib/rails/application/bootstrap.rb
@@ -16,7 +16,7 @@ module Bootstrap
16 16
       initializer :set_eager_load, :group => :all do
17 17
         if config.eager_load.nil?
18 18
           warn <<-INFO
19  
-config.eager_load is set to nil. Please update your config/environments file accordingly:
  19
+config.eager_load is set to nil. Please update your config/environments/*.rb files accordingly:
20 20
 
21 21
   * development - set it to false
22 22
   * test - set it to false (unless you use a tool that preloads your test environment)
@@ -27,13 +27,6 @@ module Bootstrap
27 27
         end
28 28
       end
29 29
 
30  
-      # Preload all frameworks specified by the Configuration#frameworks.
31  
-      # Used by Passenger to ensure everything's loaded before forking and
32  
-      # to avoid autoload race conditions in JRuby.
33  
-      initializer :preload_frameworks, :group => :all do
34  
-        ActiveSupport::Autoload.eager_autoload! if config.preload_frameworks
35  
-      end
36  
-
37 30
       # Initialize the logger early in the stack in case we need to log some deprecation.
38 31
       initializer :initialize_logger, :group => :all do
39 32
         Rails.logger ||= config.logger || begin
3  railties/lib/rails/application/configuration.rb
@@ -9,7 +9,7 @@ class Configuration < ::Rails::Engine::Configuration
9 9
                     :cache_classes, :cache_store, :consider_all_requests_local, :console,
10 10
                     :eager_load, :exceptions_app, :file_watcher, :filter_parameters,
11 11
                     :force_ssl, :helpers_paths, :logger, :log_formatter, :log_tags,
12  
-                    :preload_frameworks, :railties_order, :relative_url_root, :secret_token,
  12
+                    :railties_order, :relative_url_root, :secret_token,
13 13
                     :serve_static_assets, :ssl_options, :static_cache_control, :session_options,
14 14
                     :time_zone, :reload_classes_only_on_change,
15 15
                     :queue, :queue_consumer
@@ -95,7 +95,6 @@ def paths
95 95
       # after boot, and disables reloading code on every request, as these are
96 96
       # fundamentally incompatible with thread safety.
97 97
       def threadsafe!
98  
-        @preload_frameworks = true
99 98
         @cache_classes = true
100 99
         @eager_load = true
101 100
         self
2  railties/lib/rails/application/finisher.rb
@@ -52,7 +52,7 @@ module Finisher
52 52
       initializer :eager_load! do
53 53
         if config.eager_load
54 54
           ActiveSupport.run_load_hooks(:before_eager_load, self)
55  
-          eager_load!
  55
+          config.eager_load_namespaces.each(&:eager_load!)
56 56
         end
57 57
       end
58 58
 
5  railties/lib/rails/engine.rb
@@ -339,11 +339,16 @@ class Engine < Railtie
339 339
 
340 340
     class << self
341 341
       attr_accessor :called_from, :isolated
  342
+
342 343
       alias :isolated? :isolated
343 344
       alias :engine_name :railtie_name
344 345
 
  346
+      delegate :eager_load!, to: :instance
  347
+
345 348
       def inherited(base)
346 349
         unless base.abstract_railtie?
  350
+          Rails::Railtie::Configuration.eager_load_namespaces << base
  351
+
347 352
           base.called_from = begin
348 353
             # Remove the line number from backtraces making sure we don't leave anything behind
349 354
             call_stack = caller.map { |p| p.sub(/:\d+.*/, '') }
3  railties/lib/rails/railtie.rb
@@ -178,9 +178,6 @@ def config
178 178
       @config ||= Railtie::Configuration.new
179 179
     end
180 180
 
181  
-    def eager_load!
182  
-    end
183  
-
184 181
     def railtie_namespace
185 182
       @railtie_namespace ||= self.class.parents.detect { |n| n.respond_to?(:railtie_namespace) }
186 183
     end
10  railties/lib/rails/railtie/configuration.rb
@@ -7,6 +7,16 @@ def initialize
7 7
         @@options ||= {}
8 8
       end
9 9
 
  10
+      # Expose the eager_load_namespaces at "module" level for convenience.
  11
+      def self.eager_load_namespaces #:nodoc:
  12
+        @@eager_load_namespaces ||= []
  13
+      end
  14
+
  15
+      # All namespaces that are eager loaded
  16
+      def eager_load_namespaces
  17
+        @@eager_load_namespaces ||= []
  18
+      end
  19
+
10 20
       # Add files that should be watched for change.
11 21
       def watchable_files
12 22
         @@watchable_files ||= []
16  railties/test/application/configuration_test.rb
@@ -176,22 +176,6 @@ def teardown
176 176
       end
177 177
     end
178 178
 
179  
-    test "frameworks are not preloaded by default" do
180  
-      require "#{app_path}/config/environment"
181  
-
182  
-      assert ActionController.autoload?(:Caching)
183  
-    end
184  
-
185  
-    test "frameworks are preloaded with config.preload_frameworks is set" do
186  
-      add_to_config <<-RUBY
187  
-        config.preload_frameworks = true
188  
-      RUBY
189  
-
190  
-      require "#{app_path}/config/environment"
191  
-
192  
-      assert !ActionView.autoload?(:AssetPaths)
193  
-    end
194  
-
195 179
     test "filter_parameters should be able to set via config.filter_parameters" do
196 180
       add_to_config <<-RUBY
197 181
         config.filter_parameters += [ :foo, 'bar', lambda { |key, value|
1  railties/test/application/rake_test.rb
@@ -75,7 +75,6 @@ def world
75 75
       RUBY
76 76
 
77 77
       output = Dir.chdir(app_path){ `rake do_nothing` }
78  
-      puts output
79 78
       assert_match "Hello world", output
80 79
     end
81 80
 

0 notes on commit 2801786

Please sign in to comment.
Something went wrong with that request. Please try again.