提交 1d8623b4 编写于 作者: J Joshua Peek

Added local assign keys to compiled method name so two threads evaluating the...

Added local assign keys to compiled method name so two threads evaluating the same template with different locals don't step on top of each other
上级 7b9e8ae2
......@@ -12,7 +12,7 @@ def render
end
def method
['_run', @extension, @method_segment].compact.join('_').to_sym
['_run', @extension, @method_segment, local_assigns_keys].compact.join('_').to_sym
end
private
......@@ -28,5 +28,11 @@ def prepare!
@prepared = true
end
end
def local_assigns_keys
if @locals && @locals.any?
"locals_#{@locals.keys.map { |k| k.to_s }.sort.join('_')}"
end
end
end
end
......@@ -20,7 +20,7 @@ def initialize(view, path, use_full_path = nil, locals = {})
set_extension_and_file_name
@method_segment = compiled_method_name_file_path_segment
@locals = locals || {}
@locals = (locals && locals.dup) || {}
@handler = self.class.handler_class_for_extension(@extension).new(@view)
end
......
......@@ -5,9 +5,6 @@ def self.included(base)
base.extend ClassMethod
@@mutex = Mutex.new
# Map method names to the compiled local assigns
@@template_args = {}
end
module ClassMethod
......@@ -26,11 +23,7 @@ def compile_template(template)
return false unless recompile_template?(template)
@@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
locals_code = template.locals.keys.map { |key| "#{key} = local_assigns[:#{key}];" }.join
source = <<-end_src
def #{template.method}(local_assigns)
......@@ -69,25 +62,9 @@ def recompile_template?(template)
# Always recompile inline templates
return true if template.is_a?(InlineTemplate)
# Unless local assigns support, recompile
return true unless supports_local_assigns?(template.method, template.locals)
# Otherwise, use compiled method
return false
end
def cache_template_args(render_symbol, local_assigns)
@@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 = @@template_args[render_symbol]) && local_assigns.all? { |k,_| args.has_key?(k) })
end
end
end
end
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册