aboutsummaryrefslogtreecommitdiffstats
path: root/actionpack/lib/action_view
diff options
context:
space:
mode:
authorJoshua Peek <josh@joshpeek.com>2008-07-06 00:00:45 -0500
committerJoshua Peek <josh@joshpeek.com>2008-07-06 00:00:45 -0500
commit7b9e8ae2734089555e5bfdb9e9c80d92f43551a2 (patch)
tree4aee159e2a322d4afdd252b81ac49af00ffeb15e /actionpack/lib/action_view
parent9828aecd2aa98910f17e4b0f52519f4727d198d8 (diff)
downloadrails-7b9e8ae2734089555e5bfdb9e9c80d92f43551a2.tar.gz
rails-7b9e8ae2734089555e5bfdb9e9c80d92f43551a2.tar.bz2
rails-7b9e8ae2734089555e5bfdb9e9c80d92f43551a2.zip
Synchronize template compiling
Diffstat (limited to 'actionpack/lib/action_view')
-rw-r--r--actionpack/lib/action_view/template_handlers/compilable.rb65
1 files changed, 34 insertions, 31 deletions
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