Class: ScoutApm::LayerChildrenSet

Inherits:
Object
  • Object
show all
Includes:
Enumerable
Defined in:
lib/scout_apm/layer_children_set.rb

Overview

A set of children records for any given Layer. This implements some rate-limiting logic.

We store the first ‘unique_cutoff` count of each layer type. So if cutoff is 1000, we’d store 1000 HTTP layers, and 1000 ActiveRecord calls, and 1000 of each other layer type. After that, make a LimitedLayer object and store only aggregate counts and times of future layers of that type. (So the 1001st an onward of ActiveRecord would get only aggregate times, and counts, without any detail about the SQL called)

When the set of children is small, keep them unique When the set of children gets large enough, stop keeping details

The next optimization, which is not yet implemented:

when the set of children gets larger, attempt to merge them without data loss

Constant Summary collapse

DEFAULT_UNIQUE_CUTOFF =

By default, how many unique children of a type do we store before flipping over to storing only aggregate info.

2000

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(unique_cutoff = DEFAULT_UNIQUE_CUTOFF) ⇒ LayerChildrenSet

Returns a new instance of LayerChildrenSet.



29
30
31
32
33
# File 'lib/scout_apm/layer_children_set.rb', line 29

def initialize(unique_cutoff = DEFAULT_UNIQUE_CUTOFF)
  @children = Hash.new
  @limited_layers = nil # populated when needed
  @unique_cutoff = unique_cutoff
end

Instance Attribute Details

#unique_cutoffObject (readonly)

Returns the value of attribute unique_cutoff.



23
24
25
# File 'lib/scout_apm/layer_children_set.rb', line 23

def unique_cutoff
  @unique_cutoff
end

Instance Method Details

#<<(child) ⇒ Object

Add a new layer into this set Only add completed layers - otherwise this will collect up incorrect info into the created LimitedLayer, since it will “freeze” any current data for total_call_time and similar methods.



44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
# File 'lib/scout_apm/layer_children_set.rb', line 44

def <<(child)
  metric_type = child.type
  set = child_set(metric_type)

  if set.size >= unique_cutoff
    # find or create limited_layer
    @limited_layers ||= Hash.new 
    layer = if @limited_layers.has_key?(metric_type)
              @limited_layers[metric_type]
            else
              @limited_layers[metric_type] = LimitedLayer.new(metric_type)
            end

    layer.absorb(child)
  else
    # we have space just add it
    set << child
  end
end

#child_set(metric_type) ⇒ Object



35
36
37
38
# File 'lib/scout_apm/layer_children_set.rb', line 35

def child_set(metric_type)
  children[metric_type] = Set.new if !children.has_key?(metric_type)
  children[metric_type]
end

#eachObject



64
65
66
67
68
69
70
71
72
73
74
75
76
# File 'lib/scout_apm/layer_children_set.rb', line 64

def each
  children.each do |_type, set|
    set.each do |child_layer|
      yield child_layer
    end
  end

  if @limited_layers
    @limited_layers.each do |_type, limited_layer|
      yield limited_layer
    end
  end
end

#lengthObject



78
79
80
# File 'lib/scout_apm/layer_children_set.rb', line 78

def length
  @children.length
end

#sizeObject



82
83
84
# File 'lib/scout_apm/layer_children_set.rb', line 82

def size
  @children.size
end