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
# 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 limited_layer
    @limited_layers || init_limited_layers
    @limited_layers[metric_type].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



58
59
60
61
62
63
64
65
66
67
68
69
70
# File 'lib/scout_apm/layer_children_set.rb', line 58

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

#init_limited_layersObject

hold off initializing this until we know we need it



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

def init_limited_layers
  @limited_layers ||= Hash.new { |hash, key| hash[key] = LimitedLayer.new(key) }
end

#lengthObject



72
73
74
# File 'lib/scout_apm/layer_children_set.rb', line 72

def length
  @children.length
end

#sizeObject



76
77
78
# File 'lib/scout_apm/layer_children_set.rb', line 76

def size
  @children.size
end