Class: Quonfig::Telemetry::EvaluationSummariesAggregator

Inherits:
Object
  • Object
show all
Defined in:
lib/quonfig/telemetry/evaluation_summaries_aggregator.rb

Overview

Accumulates per-evaluation counts grouped by (config_key, config_type), with one counter per unique (config_id, conditional_value_index, weighted_value_index, selected_value). Emits api-telemetry’s ‘summaries` event — JSON wire format matching sdk-node and sdk-go.

Ported from ReforgeHQ/sdk-ruby evaluation_summary_aggregator.rb and adapted to the JSON wire format (EvaluationSummariesSchema in api-telemetry/src/telemetry-schemas.ts).

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(max_keys:) ⇒ EvaluationSummariesAggregator

Returns a new instance of EvaluationSummariesAggregator.



16
17
18
19
20
21
# File 'lib/quonfig/telemetry/evaluation_summaries_aggregator.rb', line 16

def initialize(max_keys:)
  @max_keys = max_keys
  @data = Concurrent::Hash.new
  @start_at_ms = nil
  @mutex = Mutex.new
end

Instance Attribute Details

#dataObject (readonly)

Returns the value of attribute data.



14
15
16
# File 'lib/quonfig/telemetry/evaluation_summaries_aggregator.rb', line 14

def data
  @data
end

Instance Method Details

#drain_eventObject

Drain accumulated summaries into a single telemetry event payload. Returns nil when there is nothing to ship.



59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
# File 'lib/quonfig/telemetry/evaluation_summaries_aggregator.rb', line 59

def drain_event
  snapshot = nil
  start_at = nil

  @mutex.synchronize do
    return nil if @data.empty?

    snapshot = @data
    start_at = @start_at_ms
    @data = Concurrent::Hash.new
    @start_at_ms = nil
  end

  summaries = snapshot.map do |(config_key, config_type), counters|
    counter_list = counters.map do |(config_id, cvi, wvi, sval), meta|
      counter = {
        'configId' => config_id,
        'conditionalValueIndex' => cvi,
        'configRowIndex' => 0,
        'selectedValue' => wrap_selected_value(sval),
        'count' => meta[:count],
        'reason' => meta[:reason]
      }
      counter['weightedValueIndex'] = wvi unless wvi.nil?
      counter
    end

    entry = { 'key' => config_key, 'counters' => counter_list }
    entry['type'] = config_type unless config_type.nil?
    entry
  end

  {
    'summaries' => {
      'start' => start_at || Quonfig::TimeHelpers.now_in_ms,
      'end' => Quonfig::TimeHelpers.now_in_ms,
      'summaries' => summaries
    }
  }
end

#record(config_id:, config_key:, config_type:, conditional_value_index:, weighted_value_index: nil, selected_value: nil, reason: 0) ⇒ Object

Record a single evaluation.

Parameters:

  • config_id (String)
  • config_key (String)
  • config_type (String, nil)

    “config”, “feature_flag”, etc. “log_level” evaluations are intentionally dropped (they’re high volume and not useful for usage analytics).

  • conditional_value_index (Integer)

    rule index

  • weighted_value_index (Integer, nil) (defaults to: nil)
  • selected_value (Object) (defaults to: nil)

    the unwrapped evaluated value

  • reason (Integer) (defaults to: 0)

    wire reason code (see Quonfig::Reason::WIRE_*)



34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
# File 'lib/quonfig/telemetry/evaluation_summaries_aggregator.rb', line 34

def record(config_id:, config_key:, config_type:,
           conditional_value_index:, weighted_value_index: nil,
           selected_value: nil, reason: 0)
  return if @max_keys <= 0
  return if config_type == 'log_level'

  group_key = [config_key, config_type]
  counter_key = [config_id, conditional_value_index, weighted_value_index, selected_value]

  @mutex.synchronize do
    unless @data.key?(group_key)
      return if @data.size >= @max_keys

      @data[group_key] = {}
    end
    @start_at_ms ||= Quonfig::TimeHelpers.now_in_ms

    bucket = @data[group_key]
    bucket[counter_key] ||= { count: 0, reason: reason }
    bucket[counter_key][:count] += 1
  end
end