Skip to content

Commit 86f4f4d

Browse files
committed
Use the same timer for execution and its sections to increase accurancy
1 parent ab557ad commit 86f4f4d

7 files changed

Lines changed: 57 additions & 35 deletions

File tree

lib/rorvswild/agent.rb

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -113,12 +113,10 @@ def measure_job(name, parameters: nil, &block)
113113

114114
def start_execution(execution)
115115
Thread.current[:rorvswild_execution] ||= execution
116-
RorVsWild::Section.start
117116
end
118117

119118
def stop_execution
120119
return unless execution = current_execution
121-
RorVsWild::Section.stop
122120
execution.stop
123121
case execution
124122
when Execution::Job then queue_job

lib/rorvswild/execution.rb

Lines changed: 13 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2,21 +2,21 @@
22

33
module RorVsWild
44
class Execution
5-
attr_reader :parameters, :sections, :section_stack, :error_context, :runtime
5+
attr_reader :parameters, :sections, :section_stack, :error_context, :runtime, :root_section, :queue_section
66

77
attr_accessor :error, :name
88

99
def initialize(name, parameters)
10+
@root_section = Section::Root.new
11+
1012
@name = name
1113
@parameters = parameters
1214
@runtime = nil
1315
@error = nil
1416
@error_context = nil
1517

16-
@started_at = RorVsWild.clock_milliseconds
17-
@gc_section = Section::GarbageCollection.new
1818
@environment = Host.to_h
19-
@section_stack = []
19+
@section_stack = [@root_section]
2020
@sections = []
2121
end
2222

@@ -30,20 +30,18 @@ def add_section(section)
3030

3131
def add_queue_time(queue_time_ms)
3232
return unless queue_time_ms
33-
@started_at -= queue_time_ms
34-
section = Section.new
35-
section.total_ms = queue_time_ms
36-
section.gc_time_ms = 0
37-
section.file = "queue"
38-
section.line = 0
39-
section.kind = "queue"
40-
add_section(section)
33+
@queue_section = Section::Queue.new(queue_time_ms)
34+
add_section(@queue_section)
35+
@queue_section
4136
end
4237

4338
def stop
44-
@gc_section.stop
45-
@sections << @gc_section if @gc_section.calls > 0 && @gc_section.total_ms > 0
46-
@runtime = RorVsWild.clock_milliseconds - @started_at
39+
Section.stop # root section
40+
if @root_section.gc_time_ms > 0
41+
add_section(Section::GarbageCollection.new(@root_section.gc_time_ms, @root_section.gc_calls))
42+
end
43+
@runtime = @root_section.total_ms + @root_section.gc_time_ms
44+
@runtime += @queue_section.total_ms if @queue_section
4745
end
4846

4947
def as_json(options = nil)

lib/rorvswild/plugin/rails_engine.rb

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -58,12 +58,11 @@ def call(env)
5858
execution = RorVsWild::Execution::Request.new(env["REQUEST_URI"])
5959
execution.add_queue_time(calculate_queue_time(env))
6060
RorVsWild.agent.start_execution(execution)
61-
section = RorVsWild::Section.start
61+
section = execution.root_section
6262
section.file, section.line = method(:call).super_method.source_location
6363
section.commands << "Rails::Engine#call"
6464
super
6565
ensure
66-
RorVsWild::Section.stop
6766
RorVsWild.agent.stop_execution
6867
end
6968

lib/rorvswild/section.rb

Lines changed: 30 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -97,21 +97,44 @@ def command
9797
string.size > COMMAND_MAX_SIZE ? string[0, COMMAND_MAX_SIZE] + " [TRUNCATED]" : string
9898
end
9999

100-
class GarbageCollection < Section
100+
class Root < Section
101+
attr_reader :gc_calls
102+
101103
def initialize
104+
super
102105
@gc_count = GC.count
106+
end
107+
108+
def stop
103109
super
104-
@calls = 0
110+
@gc_calls = GC.count - @gc_count
111+
end
112+
end
113+
114+
class GarbageCollection < Section
115+
def initialize(total_ms, calls)
116+
@total_ms = total_ms
117+
@calls = calls > 0 ? calls : 1
105118
@kind = "gc"
106119
@file, @line = "ruby/gc.c", 0
120+
@commands = Set.new
121+
@children_ms = 0
122+
@async_ms = 0
107123
add_command("GC.start")
108124
end
125+
end
109126

110-
def stop
111-
super
112-
@total_ms = @gc_time_ms
113-
@calls = GC.count - @gc_count
114-
@calls = 1 if @gc_time_ms > 0 && @calls == 0
127+
class Queue < Section
128+
def initialize(total_ms)
129+
@total_ms = total_ms
130+
@gc_time_ms = 0
131+
@file = "queue"
132+
@line = 0
133+
@kind = "queue"
134+
@calls = 1
135+
@children_ms = 0
136+
@gc_time_ms = 0
137+
@async_ms = 0
115138
end
116139
end
117140
end

test/execution_test.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@ def test_format_header_name
1313
def test_add_queue_time
1414
agent
1515
execution = RorVsWild::Execution.new("name", nil)
16-
old_started_at = execution.instance_variable_get(:@started_at)
1716
execution.add_queue_time(1)
17+
execution.stop
1818
assert(section = execution.sections[0])
1919
assert_equal("queue", section.kind)
2020
assert_equal("queue", section.file)
@@ -24,7 +24,7 @@ def test_add_queue_time
2424
assert_equal(0, section.children_ms)
2525
assert_equal(0, section.gc_time_ms)
2626
assert_equal(0, section.async_ms)
27-
assert_equal(old_started_at - 1, execution.instance_variable_get(:@started_at))
27+
assert_equal(execution.root_section.total_ms + execution.queue_section.total_ms, execution.runtime)
2828
end
2929

3030
def test_as_json

test/helper.rb

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,9 +41,13 @@ def client.transmit(request)
4141
agent
4242
end
4343

44-
# Returns all section except the GC and the root one which is the last
44+
# Returns all section except the GC and root
4545
def current_user_sections
46-
agent.current_execution.sections.select { |s| s.kind != "gc" }[0..-2]
46+
agent.current_execution.sections.select { |s| s.kind != "gc" && !s.is_a?(RorVsWild::Section::Root) }
47+
end
48+
49+
def current_sections_without_gc
50+
agent.current_execution.sections.select { |s| s.kind != "gc" }
4751
end
4852

4953
def start_request(path = "/")

test/plugin/rails_engine_test.rb

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,14 @@ class RorVsWild::Plugin::RailsEngineTest < Minitest::Test
66
def test_callback
77
middleware.call("REQUEST_URI" => "/foo/bar")
88
assert_equal("/foo/bar", agent.current_execution.path)
9-
assert_equal(1, (sections = current_user_sections).size)
9+
assert_equal(1, (sections = current_sections_without_gc).size)
1010
assert_equal("Rails::Engine#call", sections[0].command)
1111
end
1212

1313
def test_queue_time_section
1414
middleware.call("HTTP_X_REQUEST_START" => unix_timestamp_seconds.to_s)
1515

16-
sections = current_user_sections
16+
sections = current_sections_without_gc
1717
assert_equal(2, sections.size)
1818
queue_time_section = sections[0]
1919
assert_equal "queue", queue_time_section.file
@@ -25,23 +25,23 @@ def test_queue_time_section
2525
def test_queue_time_secs
2626
middleware.call("HTTP_X_REQUEST_START" => (unix_timestamp_seconds - 0.123).to_s)
2727

28-
sections = current_user_sections
28+
sections = current_sections_without_gc
2929
assert_equal(2, sections.size)
3030
assert_operator(123, :<=, sections[0].total_ms)
3131
end
3232

3333
def test_queue_time_millis
3434
middleware.call("HTTP_X_QUEUE_START" => (unix_timestamp_seconds * 1000 - 234).to_s)
3535

36-
sections = current_user_sections
36+
sections = current_sections_without_gc
3737
assert_equal(2, sections.size)
3838
assert_operator(234, :<=, sections[0].total_ms)
3939
end
4040

4141
def test_queue_time_micros
4242
middleware.call("HTTP_X_MIDDLEWARE_START" => (unix_timestamp_seconds * 1_000_000 - 345_000).to_s)
4343

44-
sections = current_user_sections
44+
sections = current_sections_without_gc
4545
assert_equal(2, sections.size)
4646
assert_operator(345, :<=, sections[0].total_ms)
4747
end

0 commit comments

Comments
 (0)