From 7b9e8ae2734089555e5bfdb9e9c80d92f43551a2 Mon Sep 17 00:00:00 2001 From: Joshua Peek Date: Sun, 6 Jul 2008 00:00:45 -0500 Subject: Synchronize template compiling --- .../action_view/template_handlers/compilable.rb | 65 +++++++++++----------- 1 file changed, 34 insertions(+), 31 deletions(-) (limited to 'actionpack/lib') diff --git a/actionpack/lib/action_view/template_handlers/compilable.rb b/actionpack/lib/action_view/template_handlers/compilable.rb index ed7b0e71ea..d079ef3d15 100644 --- a/actionpack/lib/action_view/template_handlers/compilable.rb +++ b/actionpack/lib/action_view/template_handlers/compilable.rb @@ -4,9 +4,10 @@ module ActionView def self.included(base) base.extend ClassMethod + @@mutex = Mutex.new + # Map method names to the compiled local assigns - base.cattr_accessor :template_args - base.template_args = {} + @@template_args = {} end module ClassMethod @@ -22,33 +23,35 @@ module ActionView # Compile and evaluate the template's code def compile_template(template) - return false unless compile_template?(template) - - locals_code = "" - locals_keys = cache_template_args(template.method, template.locals) - locals_keys.each do |key| - locals_code << "#{key} = local_assigns[:#{key}];" - end + return false unless recompile_template?(template) - source = <<-end_src - def #{template.method}(local_assigns) - old_output_buffer = output_buffer;#{locals_code};#{compile(template)} - ensure - self.output_buffer = old_output_buffer - end - end_src - - begin - file_name = template.filename || 'compiled-template' - ActionView::Base::CompiledTemplates.module_eval(source, file_name, 0) - rescue Exception => e # errors from template code - if Base.logger - Base.logger.debug "ERROR: compiling #{template.method} RAISED #{e}" - Base.logger.debug "Function body: #{source}" - Base.logger.debug "Backtrace: #{e.backtrace.join("\n")}" + @@mutex.synchronize do + locals_code = "" + locals_keys = cache_template_args(template.method, template.locals) + locals_keys.each do |key| + locals_code << "#{key} = local_assigns[:#{key}];" end - raise ActionView::TemplateError.new(template, @view.assigns, e) + source = <<-end_src + def #{template.method}(local_assigns) + old_output_buffer = output_buffer;#{locals_code};#{compile(template)} + ensure + self.output_buffer = old_output_buffer + end + end_src + + begin + file_name = template.filename || 'compiled-template' + ActionView::Base::CompiledTemplates.module_eval(source, file_name, 0) + rescue Exception => e # errors from template code + if Base.logger + Base.logger.debug "ERROR: compiling #{template.method} RAISED #{e}" + Base.logger.debug "Function body: #{source}" + Base.logger.debug "Backtrace: #{e.backtrace.join("\n")}" + end + + raise ActionView::TemplateError.new(template, @view.assigns, e) + end end end @@ -56,7 +59,7 @@ module ActionView # Method to check whether template compilation is necessary. # The template will be compiled if the inline template or file has not been compiled yet, # if local_assigns has a new key, which isn't supported by the compiled code yet. - def compile_template?(template) + def recompile_template?(template) # Unless the template has been complied yet, compile return true unless Base::CompiledTemplates.instance_methods.include?(template.method.to_s) @@ -74,16 +77,16 @@ module ActionView end def cache_template_args(render_symbol, local_assigns) - self.template_args[render_symbol] ||= {} - locals_keys = self.template_args[render_symbol].keys | local_assigns.keys - self.template_args[render_symbol] = locals_keys.inject({}) { |h, k| h[k] = true; h } + @@template_args[render_symbol] ||= {} + locals_keys = @@template_args[render_symbol].keys | local_assigns.keys + @@template_args[render_symbol] = locals_keys.inject({}) { |h, k| h[k] = true; h } locals_keys end # Return true if the given template was compiled for a superset of the keys in local_assigns def supports_local_assigns?(render_symbol, local_assigns) local_assigns.empty? || - ((args = self.template_args[render_symbol]) && local_assigns.all? { |k,_| args.has_key?(k) }) + ((args = @@template_args[render_symbol]) && local_assigns.all? { |k,_| args.has_key?(k) }) end end end -- cgit v1.2.3