Class: RailsTracepointStack::DepthTracker

Inherits:
Object
  • Object
show all
Defined in:
lib/rails_tracepoint_stack/depth_tracker.rb

Overview

Turns raw stack positions into app-level nesting.

Counting :call and :return events would not work here, for two reasons. Most frames between two traced methods belong to gems and get filtered out, so an event counter would indent app code by the depth of the framework underneath it. And the tracer does not always watch :return at all - the global tracer only subscribes to :call - so nothing would ever pop.

Reading the real stack position of each kept trace avoids both. A frame recorded at an equal or deeper position has necessarily finished, whether it returned, raised, or was abandoned, so it gets dropped on the next event rather than waiting for one that may never arrive.

Instance Method Summary collapse

Constructor Details

#initializeDepthTracker

Returns a new instance of DepthTracker.



15
16
17
# File 'lib/rails_tracepoint_stack/depth_tracker.rb', line 15

def initialize
  @stack = []
end

Instance Method Details

#enter(raw_position) ⇒ Object



19
20
21
22
23
24
# File 'lib/rails_tracepoint_stack/depth_tracker.rb', line 19

def enter(raw_position)
  drop_finished_frames(raw_position, inclusive: true)
  depth = @stack.size
  @stack.push(raw_position)
  depth
end

#leave(raw_position) ⇒ Object



26
27
28
29
30
31
32
# File 'lib/rails_tracepoint_stack/depth_tracker.rb', line 26

def leave(raw_position)
  drop_finished_frames(raw_position, inclusive: false)
  return @stack.size unless @stack.last == raw_position

  @stack.pop
  @stack.size
end

#raised(raw_position) ⇒ Object

A raise belongs to the innermost frame being tracked. It may report a position deeper than that frame when the exception comes out of a C method the app called, such as an arithmetic coercion, and there is no tracked frame down there to attribute it to.



38
39
40
41
42
# File 'lib/rails_tracepoint_stack/depth_tracker.rb', line 38

def raised(raw_position)
  drop_finished_frames(raw_position, inclusive: false)

  [@stack.size - 1, 0].max
end