Skip to content
This repository
Browse code

Ensure config.after_initializer is executed before building the middl…

…eware stack.
  • Loading branch information...
commit a5684dfa3c16472bfa5d5d861ba78cb6dbadcb59 1 parent 1477a61
José Valim authored
10  railties/lib/rails/application/finisher.rb
@@ -27,17 +27,19 @@ module Finisher
27 27
         end
28 28
       end
29 29
 
30  
-      initializer :build_middleware_stack do
31  
-        app
32  
-      end
33  
-
34 30
       # Fires the user-supplied after_initialize block (config.after_initialize)
  31
+      # Should run before the middleware stack is built, because building the
  32
+      # middleware already fires to_prepare callbacks in test and production.
35 33
       initializer :after_initialize do
36 34
         config.after_initialize_blocks.each do |block|
37 35
           block.call(self)
38 36
         end
39 37
       end
40 38
 
  39
+      initializer :build_middleware_stack do
  40
+        app
  41
+      end
  42
+
41 43
       # Disable dependency loading during request cycle
42 44
       initializer :disable_dependency_loading do
43 45
         if config.cache_classes && !config.dependency_loading
1  railties/lib/rails/engine.rb
@@ -15,6 +15,7 @@ class << self
15 15
       def inherited(base)
16 16
         unless abstract_railtie?(base)
17 17
           base.called_from = begin
  18
+            # Remove the line number from backtraces making sure we don't leave anything behind
18 19
             call_stack = caller.map { |p| p.split(':')[0..-2].join(':') }
19 20
             File.dirname(call_stack.detect { |p| p !~ %r[railties[\w\-]*/lib/rails|rack[\w\-]*/lib/rack] })
20 21
           end
14  railties/test/application/initializers/initializers_test.rb
@@ -51,5 +51,19 @@ def setup
51 51
       assert $activerecord_configurations
52 52
       assert $activerecord_configurations['development']
53 53
     end
  54
+
  55
+    test "after_initialize happens before to_prepare (i.e. before the middleware stack is built) on production" do
  56
+      $order = []
  57
+      add_to_config <<-RUBY
  58
+        config.after_initialize { $order << :after_initialize }
  59
+        config.to_prepare { $order << :to_prepare }
  60
+      RUBY
  61
+
  62
+      require "#{app_path}/config/application"
  63
+      Rails.env.replace "production"
  64
+      require "#{app_path}/config/environment"
  65
+      assert [:after_initialize, :to_prepare], $order
  66
+    end
  67
+
54 68
   end
55 69
 end

4 notes on commit a5684df

Joshua Peek
Collaborator

I thought I had a test that asserted just the opposite. "after initialize" should be like it says after, not before middleware initializers run.

José Valim
Owner

I ran the test suite and it passed. The problem is when you build the middleware stack in production, it executes :to_prepare callbacks and it breaks the behavior in comparison if what happens in development, where to prepare callbacks are called just before the first request. In other words, the order things are being setup would change from environment to environment.

Joshua Peek
Collaborator

to_prepare should be called before after_initialize in dev mode too. Then before every request.

José Valim
Owner

If so, it makes sense. I remember changing to_prepare to work just before each request in development so application would load faster for things like rake. Do you want me to revert both changes?

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