aboutsummaryrefslogtreecommitdiffstats
path: root/actionview/lib
diff options
context:
space:
mode:
authorSimon Coffey <simon@urbanautomaton.com>2018-03-30 22:45:57 +0100
committerSimon Coffey <simon@urbanautomaton.com>2018-04-02 20:50:33 +0100
commiteede8d8130558cb46aba8736bd63e8a28e37eac2 (patch)
tree2fd0d317f82cc3577d6f1d6b93e35432861ef648 /actionview/lib
parent073168358740b33831f0963242ba1de1d0ddb0cc (diff)
downloadrails-eede8d8130558cb46aba8736bd63e8a28e37eac2.tar.gz
rails-eede8d8130558cb46aba8736bd63e8a28e37eac2.tar.bz2
rails-eede8d8130558cb46aba8736bd63e8a28e37eac2.zip
Add `action_view.finalize_compiled_template_methods` config option
ActionView::Template instances compile their source to methods on the ActionView::CompiledTemplates module. To prevent leaks in development mode, where templates can frequently change, a finalizer is added that undefines these methods[1] when the templates are garbage-collected. This is undesirable in the test environment, however, as templates don't change during the life of the test. Moreover, the cost of undefining a method is proportional to the number of descendants a class or module has, since the method cache must be cleared for all descendant classes. As ActionView::CompiledTemplates is mixed into every ActionView::TestCase (or in RSpec suites, every view spec example group), it can end up with a very large number of descendants, and undefining its methods can become very expensive. In large test suites, this results in a long delay at the end of the test suite as all template finalizers are run, only for the process to then exit. To avoid this unnecessary cost, this change adds a config option, `action_view.finalize_compiled_template_methods`, defaulting to true, and sets it to false in the test environment only. [1] https://github.com/rails/rails/blob/09b2348f7fc8d4e7191e70e06608c5909067e2aa/actionview/lib/action_view/template.rb#L118-L126
Diffstat (limited to 'actionview/lib')
-rw-r--r--actionview/lib/action_view/railtie.rb8
-rw-r--r--actionview/lib/action_view/template.rb7
2 files changed, 14 insertions, 1 deletions
diff --git a/actionview/lib/action_view/railtie.rb b/actionview/lib/action_view/railtie.rb
index 12bdc642d4..12d06bf376 100644
--- a/actionview/lib/action_view/railtie.rb
+++ b/actionview/lib/action_view/railtie.rb
@@ -10,6 +10,7 @@ module ActionView
config.action_view.embed_authenticity_token_in_remote_forms = nil
config.action_view.debug_missing_translation = true
config.action_view.default_enforce_utf8 = nil
+ config.action_view.finalize_compiled_template_methods = true
config.eager_load_namespaces << ActionView
@@ -45,6 +46,13 @@ module ActionView
end
end
+ initializer "action_view.finalize_compiled_template_methods" do |app|
+ ActiveSupport.on_load(:action_view) do
+ ActionView::Template.finalize_compiled_template_methods =
+ app.config.action_view.delete(:finalize_compiled_template_methods)
+ end
+ end
+
initializer "action_view.logger" do
ActiveSupport.on_load(:action_view) { self.logger ||= Rails.logger }
end
diff --git a/actionview/lib/action_view/template.rb b/actionview/lib/action_view/template.rb
index 0c4bb73acb..1c8713d6e3 100644
--- a/actionview/lib/action_view/template.rb
+++ b/actionview/lib/action_view/template.rb
@@ -9,6 +9,9 @@ module ActionView
class Template
extend ActiveSupport::Autoload
+ mattr_accessor :finalize_compiled_template_methods
+ self.finalize_compiled_template_methods = true
+
# === Encodings in ActionView::Template
#
# ActionView::Template is one of a few sources of potential
@@ -307,7 +310,9 @@ module ActionView
end
mod.module_eval(source, identifier, 0)
- ObjectSpace.define_finalizer(self, Finalizer[method_name, mod])
+ if finalize_compiled_template_methods
+ ObjectSpace.define_finalizer(self, Finalizer[method_name, mod])
+ end
end
def handle_render_error(view, e)