Store the profiler in the context instead of a thread-local variable (#1364)

This commit is contained in:
Dylan Thacker-Smith
2020-12-09 10:04:20 -05:00
committed by GitHub
parent 7361220af6
commit 60214b957c
3 changed files with 33 additions and 26 deletions
+9 -19
View File
@@ -85,21 +85,6 @@ module Liquid
end end
end end
def self.profile_node_render(node, template_name)
if Profiler.current_profile && node.respond_to?(:render)
Profiler.current_profile.start_node(node, template_name)
output = yield
Profiler.current_profile.end_node
output
else
yield
end
end
def self.current_profile
Thread.current[:liquid_profiler]
end
attr_reader :total_render_time attr_reader :total_render_time
def initialize def initialize
@@ -108,12 +93,10 @@ module Liquid
end end
def start def start
Thread.current[:liquid_profiler] = self
@render_start_at = monotonic_time @render_start_at = monotonic_time
end end
def stop def stop
Thread.current[:liquid_profiler] = nil
@total_render_time = monotonic_time - @render_start_at @total_render_time = monotonic_time - @render_start_at
end end
@@ -129,6 +112,15 @@ module Liquid
@root_timing.children.length @root_timing.children.length
end end
def profile_node(node, template_name)
start_node(node, template_name)
yield
ensure
end_node
end
private
def start_node(node, template_name) def start_node(node, template_name)
@timing_stack.push(Timing.start(node, template_name)) @timing_stack.push(Timing.start(node, template_name))
end end
@@ -140,8 +132,6 @@ module Liquid
@timing_stack.last.children << timing @timing_stack.last.children << timing
end end
private
def monotonic_time def monotonic_time
Process.clock_gettime(Process::CLOCK_MONOTONIC) Process.clock_gettime(Process::CLOCK_MONOTONIC)
end end
+16 -1
View File
@@ -3,10 +3,25 @@
module Liquid module Liquid
module BlockBodyProfilingHook module BlockBodyProfilingHook
def render_node(context, output, node) def render_node(context, output, node)
Profiler.profile_node_render(node, context.template_name) do if (profiler = context.profiler)
profiler.profile_node(node, context.template_name) do
super
end
else
super super
end end
end end
end end
BlockBody.prepend(BlockBodyProfilingHook) BlockBody.prepend(BlockBodyProfilingHook)
module ContextProfilingHook
attr_accessor :profiler
def new_isolated_subcontext
new_context = super
new_context.profiler = profiler
new_context
end
end
Context.prepend(ContextProfilingHook)
end end
+8 -6
View File
@@ -106,9 +106,13 @@ module Liquid
# Parse source code. # Parse source code.
# Returns self for easy chaining # Returns self for easy chaining
def parse(source, options = {}) def parse(source, options = {})
if (profiling = options[:profile])
raise "Profiler not loaded, require 'liquid/profiler' first" unless defined?(Liquid::Profiler)
end
@options = options @options = options
@profiling = options[:profile] @profiling = profiling
@line_numbers = options[:line_numbers] || @profiling @line_numbers = options[:line_numbers] || profiling
parse_context = options.is_a?(ParseContext) ? options : ParseContext.new(options) parse_context = options.is_a?(ParseContext) ? options : ParseContext.new(options)
@root = Document.parse(tokenize(source), parse_context) @root = Document.parse(tokenize(source), parse_context)
@warnings = parse_context.warnings @warnings = parse_context.warnings
@@ -217,10 +221,8 @@ module Liquid
end end
def with_profiling(context) def with_profiling(context)
if @profiling && !context.partial if @profiling && context.profiler.nil?
raise "Profiler not loaded, require 'liquid/profiler' first" unless defined?(Liquid::Profiler) @profiler = context.profiler = Profiler.new
@profiler = Profiler.new
@profiler.start @profiler.start
begin begin