splitclient-rb 4.5.1-java
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +45 -0
- data/CHANGES.txt +147 -0
- data/Detailed-README.md +571 -0
- data/Gemfile +4 -0
- data/LICENSE +13 -0
- data/NEWS +75 -0
- data/README.md +43 -0
- data/Rakefile +24 -0
- data/exe/splitio +96 -0
- data/ext/murmurhash/MurmurHash3.java +162 -0
- data/lib/murmurhash/base.rb +58 -0
- data/lib/murmurhash/murmurhash.jar +0 -0
- data/lib/murmurhash/murmurhash_mri.rb +3 -0
- data/lib/splitclient-rb.rb +90 -0
- data/lib/splitclient-rb/cache/adapters/memory_adapter.rb +12 -0
- data/lib/splitclient-rb/cache/adapters/memory_adapters/map_adapter.rb +133 -0
- data/lib/splitclient-rb/cache/adapters/memory_adapters/queue_adapter.rb +44 -0
- data/lib/splitclient-rb/cache/adapters/redis_adapter.rb +165 -0
- data/lib/splitclient-rb/cache/repositories/events/memory_repository.rb +30 -0
- data/lib/splitclient-rb/cache/repositories/events/redis_repository.rb +29 -0
- data/lib/splitclient-rb/cache/repositories/events_repository.rb +41 -0
- data/lib/splitclient-rb/cache/repositories/impressions/memory_repository.rb +49 -0
- data/lib/splitclient-rb/cache/repositories/impressions/redis_repository.rb +78 -0
- data/lib/splitclient-rb/cache/repositories/impressions_repository.rb +21 -0
- data/lib/splitclient-rb/cache/repositories/metrics/memory_repository.rb +129 -0
- data/lib/splitclient-rb/cache/repositories/metrics/redis_repository.rb +98 -0
- data/lib/splitclient-rb/cache/repositories/metrics_repository.rb +22 -0
- data/lib/splitclient-rb/cache/repositories/repository.rb +23 -0
- data/lib/splitclient-rb/cache/repositories/segments_repository.rb +82 -0
- data/lib/splitclient-rb/cache/repositories/splits_repository.rb +106 -0
- data/lib/splitclient-rb/cache/routers/impression_router.rb +52 -0
- data/lib/splitclient-rb/cache/senders/events_sender.rb +47 -0
- data/lib/splitclient-rb/cache/senders/impressions_formatter.rb +73 -0
- data/lib/splitclient-rb/cache/senders/impressions_sender.rb +67 -0
- data/lib/splitclient-rb/cache/senders/metrics_sender.rb +49 -0
- data/lib/splitclient-rb/cache/stores/sdk_blocker.rb +48 -0
- data/lib/splitclient-rb/cache/stores/segment_store.rb +82 -0
- data/lib/splitclient-rb/cache/stores/split_store.rb +97 -0
- data/lib/splitclient-rb/clients/localhost_split_client.rb +92 -0
- data/lib/splitclient-rb/clients/split_client.rb +214 -0
- data/lib/splitclient-rb/engine/api/client.rb +74 -0
- data/lib/splitclient-rb/engine/api/events.rb +48 -0
- data/lib/splitclient-rb/engine/api/faraday_middleware/gzip.rb +55 -0
- data/lib/splitclient-rb/engine/api/impressions.rb +42 -0
- data/lib/splitclient-rb/engine/api/metrics.rb +61 -0
- data/lib/splitclient-rb/engine/api/segments.rb +62 -0
- data/lib/splitclient-rb/engine/api/splits.rb +60 -0
- data/lib/splitclient-rb/engine/evaluator/splitter.rb +123 -0
- data/lib/splitclient-rb/engine/matchers/all_keys_matcher.rb +46 -0
- data/lib/splitclient-rb/engine/matchers/between_matcher.rb +56 -0
- data/lib/splitclient-rb/engine/matchers/combiners.rb +9 -0
- data/lib/splitclient-rb/engine/matchers/combining_matcher.rb +86 -0
- data/lib/splitclient-rb/engine/matchers/contains_all_matcher.rb +21 -0
- data/lib/splitclient-rb/engine/matchers/contains_any_matcher.rb +19 -0
- data/lib/splitclient-rb/engine/matchers/contains_matcher.rb +30 -0
- data/lib/splitclient-rb/engine/matchers/dependency_matcher.rb +20 -0
- data/lib/splitclient-rb/engine/matchers/ends_with_matcher.rb +26 -0
- data/lib/splitclient-rb/engine/matchers/equal_to_boolean_matcher.rb +27 -0
- data/lib/splitclient-rb/engine/matchers/equal_to_matcher.rb +54 -0
- data/lib/splitclient-rb/engine/matchers/equal_to_set_matcher.rb +19 -0
- data/lib/splitclient-rb/engine/matchers/greater_than_or_equal_to_matcher.rb +53 -0
- data/lib/splitclient-rb/engine/matchers/less_than_or_equal_to_matcher.rb +53 -0
- data/lib/splitclient-rb/engine/matchers/matches_string_matcher.rb +24 -0
- data/lib/splitclient-rb/engine/matchers/negation_matcher.rb +60 -0
- data/lib/splitclient-rb/engine/matchers/part_of_set_matcher.rb +23 -0
- data/lib/splitclient-rb/engine/matchers/set_matcher.rb +20 -0
- data/lib/splitclient-rb/engine/matchers/starts_with_matcher.rb +26 -0
- data/lib/splitclient-rb/engine/matchers/user_defined_segment_matcher.rb +45 -0
- data/lib/splitclient-rb/engine/matchers/whitelist_matcher.rb +66 -0
- data/lib/splitclient-rb/engine/metrics/binary_search_latency_tracker.rb +128 -0
- data/lib/splitclient-rb/engine/metrics/metrics.rb +83 -0
- data/lib/splitclient-rb/engine/models/label.rb +8 -0
- data/lib/splitclient-rb/engine/models/split.rb +17 -0
- data/lib/splitclient-rb/engine/models/treatment.rb +3 -0
- data/lib/splitclient-rb/engine/parser/condition.rb +210 -0
- data/lib/splitclient-rb/engine/parser/evaluator.rb +118 -0
- data/lib/splitclient-rb/engine/parser/partition.rb +35 -0
- data/lib/splitclient-rb/engine/parser/split_adapter.rb +88 -0
- data/lib/splitclient-rb/exceptions/impressions_shutdown_exception.rb +4 -0
- data/lib/splitclient-rb/exceptions/sdk_blocker_timeout_expired_exception.rb +4 -0
- data/lib/splitclient-rb/localhost_split_factory.rb +13 -0
- data/lib/splitclient-rb/localhost_utils.rb +36 -0
- data/lib/splitclient-rb/managers/localhost_split_manager.rb +45 -0
- data/lib/splitclient-rb/managers/split_manager.rb +77 -0
- data/lib/splitclient-rb/split_config.rb +391 -0
- data/lib/splitclient-rb/split_factory.rb +35 -0
- data/lib/splitclient-rb/split_factory_builder.rb +16 -0
- data/lib/splitclient-rb/utilitites.rb +41 -0
- data/lib/splitclient-rb/version.rb +3 -0
- data/splitclient-rb.gemspec +50 -0
- data/splitio.yml.example +7 -0
- data/tasks/benchmark_get_treatment.rake +43 -0
- data/tasks/irb.rake +4 -0
- data/tasks/rspec.rake +3 -0
- metadata +321 -0
@@ -0,0 +1,30 @@
|
|
1
|
+
module SplitIoClient
|
2
|
+
module Cache
|
3
|
+
module Repositories
|
4
|
+
module Events
|
5
|
+
class MemoryRepository < EventsRepository
|
6
|
+
EVENTS_SLICE = 100
|
7
|
+
|
8
|
+
def initialize(adapter, config)
|
9
|
+
@adapter = adapter
|
10
|
+
@config = config
|
11
|
+
end
|
12
|
+
|
13
|
+
def add(key, traffic_type, event_type, time, value)
|
14
|
+
@adapter.add_to_queue(m: metadata, e: event(key, traffic_type, event_type, time, value))
|
15
|
+
rescue ThreadError # queue is full
|
16
|
+
if @config.debug_enabled
|
17
|
+
@config.logger.warn("Dropping events. Current size is #{@config.events_queue_size}. " \
|
18
|
+
"Consider increasing events_queue_size")
|
19
|
+
end
|
20
|
+
@adapter.clear
|
21
|
+
end
|
22
|
+
|
23
|
+
def clear
|
24
|
+
@adapter.clear
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module SplitIoClient
|
2
|
+
module Cache
|
3
|
+
module Repositories
|
4
|
+
module Events
|
5
|
+
class RedisRepository < EventsRepository
|
6
|
+
EVENTS_SLICE = 100
|
7
|
+
|
8
|
+
def initialize(adapter, config)
|
9
|
+
@adapter = adapter
|
10
|
+
@config = config
|
11
|
+
end
|
12
|
+
|
13
|
+
def add(key, traffic_type, event_type, time, value)
|
14
|
+
@adapter.add_to_queue(
|
15
|
+
namespace_key('.events'),
|
16
|
+
{ m: metadata, e: event(key, traffic_type, event_type, time, value) }.to_json,
|
17
|
+
)
|
18
|
+
end
|
19
|
+
|
20
|
+
def clear
|
21
|
+
@adapter.get_from_queue(namespace_key('.events'), EVENTS_SLICE).map do |e|
|
22
|
+
JSON.parse(e, symbolize_names: true)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
module SplitIoClient
|
2
|
+
module Cache
|
3
|
+
module Repositories
|
4
|
+
# Repository which forwards events interface to the selected adapter
|
5
|
+
class EventsRepository < Repository
|
6
|
+
extend Forwardable
|
7
|
+
def_delegators :@adapter, :add, :clear
|
8
|
+
|
9
|
+
def initialize(adapter, config)
|
10
|
+
@config = config
|
11
|
+
@adapter = case adapter.class.to_s
|
12
|
+
when 'SplitIoClient::Cache::Adapters::MemoryAdapter'
|
13
|
+
Repositories::Events::MemoryRepository.new(adapter, config)
|
14
|
+
when 'SplitIoClient::Cache::Adapters::RedisAdapter'
|
15
|
+
Repositories::Events::RedisRepository.new(adapter, config)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
protected
|
20
|
+
|
21
|
+
def metadata
|
22
|
+
{
|
23
|
+
s: "#{@config.language}-#{@config.version}",
|
24
|
+
i: @config.machine_ip,
|
25
|
+
n: @config.machine_name
|
26
|
+
}
|
27
|
+
end
|
28
|
+
|
29
|
+
def event(key, traffic_type, event_type, time, value)
|
30
|
+
{
|
31
|
+
key: key,
|
32
|
+
trafficTypeName: traffic_type,
|
33
|
+
eventTypeId: event_type,
|
34
|
+
value: value,
|
35
|
+
timestamp: time
|
36
|
+
}.reject { |_, v| v.nil? }
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
module SplitIoClient
|
2
|
+
module Cache
|
3
|
+
module Repositories
|
4
|
+
module Impressions
|
5
|
+
class MemoryRepository
|
6
|
+
def initialize(adapter, config)
|
7
|
+
@adapter = adapter
|
8
|
+
@config = config
|
9
|
+
end
|
10
|
+
|
11
|
+
# Store impression data in the selected adapter
|
12
|
+
def add(split_name, data)
|
13
|
+
@adapter.add_to_queue(feature: split_name, impressions: data)
|
14
|
+
rescue ThreadError # queue is full
|
15
|
+
if random_sampler.rand(1..1000) <= 2 # log only 0.2 % of the time
|
16
|
+
@config.logger.warn("Dropping impressions. Current size is #{@config.impressions_queue_size}. " \
|
17
|
+
"Consider increasing impressions_queue_size")
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def add_bulk(key, bucketing_key, treatments_labels_change_numbers, time)
|
22
|
+
treatments_labels_change_numbers.each do |split_name, treatment_label_number|
|
23
|
+
add(
|
24
|
+
split_name,
|
25
|
+
'keyName' => key,
|
26
|
+
'bucketingKey' => bucketing_key,
|
27
|
+
'treatment' => treatment_label_number[:treatment],
|
28
|
+
'label' => @config.labels_enabled ? treatment_label_number[:label] : nil,
|
29
|
+
'changeNumber' => treatment_label_number[:change_number],
|
30
|
+
'time' => time
|
31
|
+
)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
# Get everything from the queue and leave it empty
|
36
|
+
def clear
|
37
|
+
@adapter.clear.map { |impression| impression.update(ip: @config.machine_ip) }
|
38
|
+
end
|
39
|
+
|
40
|
+
private
|
41
|
+
|
42
|
+
def random_sampler
|
43
|
+
@random_sampler ||= Random.new
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,78 @@
|
|
1
|
+
module SplitIoClient
|
2
|
+
module Cache
|
3
|
+
module Repositories
|
4
|
+
module Impressions
|
5
|
+
class RedisRepository < Repository
|
6
|
+
IMPRESSIONS_SLICE = 1000
|
7
|
+
|
8
|
+
def initialize(adapter, config)
|
9
|
+
@adapter = adapter
|
10
|
+
@config = config
|
11
|
+
end
|
12
|
+
|
13
|
+
# Store impression data in Redis
|
14
|
+
def add(split_name, data)
|
15
|
+
@adapter.add_to_set(
|
16
|
+
impressions_metrics_key("impressions.#{split_name}"),
|
17
|
+
data.to_json
|
18
|
+
)
|
19
|
+
end
|
20
|
+
|
21
|
+
def add_bulk(key, bucketing_key, treatments_labels_change_numbers, time)
|
22
|
+
@adapter.redis.pipelined do
|
23
|
+
treatments_labels_change_numbers.each_slice(IMPRESSIONS_SLICE) do |treatments_labels_change_numbers_slice|
|
24
|
+
treatments_labels_change_numbers_slice.each do |split_name, treatment_label_change_number|
|
25
|
+
add(split_name,
|
26
|
+
'keyName' => key,
|
27
|
+
'bucketingKey' => bucketing_key,
|
28
|
+
'treatment' => treatment_label_change_number[:treatment],
|
29
|
+
'label' => @config.labels_enabled ? treatment_label_change_number[:label] : nil,
|
30
|
+
'changeNumber' => treatment_label_change_number[:change_number],
|
31
|
+
'time' => time)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
# Get random impressions from redis in batches of size @config.impressions_queue_size,
|
38
|
+
# delete fetched impressions afterwards
|
39
|
+
def clear
|
40
|
+
impressions = impression_keys.each_with_object([]) do |key, memo|
|
41
|
+
ip = key.split('/')[-2] # 'prefix/sdk_lang/ip/impressions.name' -> ip
|
42
|
+
if ip.nil?
|
43
|
+
@config.logger.warn("Impressions IP parse error for key: #{key}")
|
44
|
+
next
|
45
|
+
end
|
46
|
+
split_name = key.split('.').last
|
47
|
+
members = @adapter.random_set_elements(key, @config.impressions_queue_size)
|
48
|
+
members.each do |impression|
|
49
|
+
parsed_impression = JSON.parse(impression)
|
50
|
+
|
51
|
+
memo << {
|
52
|
+
feature: split_name.to_sym,
|
53
|
+
impressions: parsed_impression,
|
54
|
+
ip: ip
|
55
|
+
}
|
56
|
+
end
|
57
|
+
|
58
|
+
@adapter.delete_from_set(key, members)
|
59
|
+
end
|
60
|
+
|
61
|
+
impressions
|
62
|
+
rescue StandardError => e
|
63
|
+
@config.logger.error("Exception while clearing impressions cache: #{e}")
|
64
|
+
end
|
65
|
+
|
66
|
+
private
|
67
|
+
|
68
|
+
# Get all sets by prefix
|
69
|
+
def impression_keys
|
70
|
+
@adapter.find_sets_by_prefix("#{@config.redis_namespace}/*/impressions.*")
|
71
|
+
rescue StandardError => e
|
72
|
+
@config.logger.error("Exception while fetching impression_keys: #{e}")
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module SplitIoClient
|
2
|
+
module Cache
|
3
|
+
module Repositories
|
4
|
+
# Repository which forwards impressions interface to the selected adapter
|
5
|
+
class ImpressionsRepository < Repository
|
6
|
+
extend Forwardable
|
7
|
+
def_delegators :@adapter, :add, :add_bulk, :clear, :empty?
|
8
|
+
|
9
|
+
def initialize(adapter, config)
|
10
|
+
@config = config
|
11
|
+
@adapter = case adapter.class.to_s
|
12
|
+
when 'SplitIoClient::Cache::Adapters::MemoryAdapter'
|
13
|
+
Repositories::Impressions::MemoryRepository.new(adapter, config)
|
14
|
+
when 'SplitIoClient::Cache::Adapters::RedisAdapter'
|
15
|
+
Repositories::Impressions::RedisRepository.new(adapter, config)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,129 @@
|
|
1
|
+
module SplitIoClient
|
2
|
+
module Cache
|
3
|
+
module Repositories
|
4
|
+
module Metrics
|
5
|
+
class MemoryRepository
|
6
|
+
def initialize(_ = nil, adapter, config)
|
7
|
+
@counts = []
|
8
|
+
@latencies = []
|
9
|
+
@gauges = []
|
10
|
+
|
11
|
+
@config = config
|
12
|
+
end
|
13
|
+
|
14
|
+
def add_count(counter, delta)
|
15
|
+
counter_hash = @counts.find { |c| c[:name] == counter }
|
16
|
+
if counter_hash.nil?
|
17
|
+
counter_delta = SumAndCount.new
|
18
|
+
counter_delta.add_delta(delta)
|
19
|
+
@counts << { name: counter, delta: counter_delta }
|
20
|
+
else
|
21
|
+
counter_hash[:delta].add_delta(delta)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def add_latency(operation, time_in_ms, binary_search)
|
26
|
+
operation_hash = @latencies.find { |l| l[:operation] == operation }
|
27
|
+
if operation_hash.nil?
|
28
|
+
latencies_for_op = (operation == 'sdk.get_treatment') ? binary_search.add_latency_millis(time_in_ms) : [time_in_ms]
|
29
|
+
@latencies << { operation: operation, latencies: latencies_for_op }
|
30
|
+
else
|
31
|
+
latencies_for_op = (operation == 'sdk.get_treatment') ? binary_search.add_latency_millis(time_in_ms) : operation_hash[:latencies].push(time_in_ms)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def add_gauge(gauge, value)
|
36
|
+
gauge_hash = @gauges.find { |g| g[:name] == gauge }
|
37
|
+
if gauge_hash.nil?
|
38
|
+
gauge_value = ValueAndCount.new
|
39
|
+
gauge_value.set_value(value)
|
40
|
+
@gauges << { name: gauge, value: gauge_value }
|
41
|
+
else
|
42
|
+
gauge_hash[:value].set_value(value)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def counts
|
47
|
+
@counts.each_with_object({}) do |count, memo|
|
48
|
+
memo[count[:name]] = count[:delta].sum
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
def latencies
|
53
|
+
@latencies.each_with_object({}) do |latency, memo|
|
54
|
+
memo[latency[:operation]] = latency[:latencies]
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
def gauges
|
59
|
+
# TODO
|
60
|
+
end
|
61
|
+
|
62
|
+
def clear_counts
|
63
|
+
@counts = []
|
64
|
+
end
|
65
|
+
|
66
|
+
def clear_latencies
|
67
|
+
@latencies = []
|
68
|
+
end
|
69
|
+
|
70
|
+
def clear_gauges
|
71
|
+
@gauges = []
|
72
|
+
end
|
73
|
+
|
74
|
+
def clear
|
75
|
+
clear_counts
|
76
|
+
clear_latencies
|
77
|
+
clear_gauges
|
78
|
+
end
|
79
|
+
|
80
|
+
#
|
81
|
+
# small class to act as DTO for counts
|
82
|
+
#
|
83
|
+
class SumAndCount
|
84
|
+
attr_reader :count
|
85
|
+
attr_reader :sum
|
86
|
+
|
87
|
+
def initialize
|
88
|
+
@count = 0
|
89
|
+
@sum = 0
|
90
|
+
end
|
91
|
+
|
92
|
+
def add_delta(delta)
|
93
|
+
@count += 1
|
94
|
+
@sum += delta
|
95
|
+
end
|
96
|
+
|
97
|
+
def clear
|
98
|
+
@count = 0
|
99
|
+
@sum = 0
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
#
|
104
|
+
# small class to act as DTO for gauges
|
105
|
+
#
|
106
|
+
class ValueAndCount
|
107
|
+
attr_reader :count
|
108
|
+
attr_reader :value
|
109
|
+
|
110
|
+
def initialize
|
111
|
+
@count = 0
|
112
|
+
@value = 0
|
113
|
+
end
|
114
|
+
|
115
|
+
def set_value(value)
|
116
|
+
@count += 1
|
117
|
+
@value = value
|
118
|
+
end
|
119
|
+
|
120
|
+
def clear
|
121
|
+
@count = 0
|
122
|
+
@value = 0
|
123
|
+
end
|
124
|
+
end
|
125
|
+
end
|
126
|
+
end
|
127
|
+
end
|
128
|
+
end
|
129
|
+
end
|
@@ -0,0 +1,98 @@
|
|
1
|
+
module SplitIoClient
|
2
|
+
module Cache
|
3
|
+
module Repositories
|
4
|
+
module Metrics
|
5
|
+
class RedisRepository < Repository
|
6
|
+
def initialize(adapter = nil, config)
|
7
|
+
@config = config
|
8
|
+
@adapter = adapter
|
9
|
+
end
|
10
|
+
|
11
|
+
def add_count(counter, delta)
|
12
|
+
prefixed_name = impressions_metrics_key("count.#{counter}")
|
13
|
+
counts = @adapter.find_strings_by_prefix(prefixed_name)
|
14
|
+
|
15
|
+
@adapter.inc(prefixed_name, delta)
|
16
|
+
end
|
17
|
+
|
18
|
+
def add_latency(operation, time_in_ms, binary_search)
|
19
|
+
prefixed_name = impressions_metrics_key("latency.#{operation}")
|
20
|
+
latencies = @adapter.find_strings_by_prefix(prefixed_name)
|
21
|
+
|
22
|
+
if operation == 'sdk.get_treatment'
|
23
|
+
@adapter.inc("#{prefixed_name}.#{binary_search.add_latency_millis(time_in_ms, true)}")
|
24
|
+
return
|
25
|
+
end
|
26
|
+
|
27
|
+
@adapter.append_to_string(prefixed_name, "#{time_in_ms},")
|
28
|
+
end
|
29
|
+
|
30
|
+
def add_gauge(gauge, value)
|
31
|
+
# TODO
|
32
|
+
end
|
33
|
+
|
34
|
+
def counts
|
35
|
+
keys = @adapter.find_strings_by_prefix(impressions_metrics_key("count"))
|
36
|
+
|
37
|
+
return [] if keys.empty?
|
38
|
+
|
39
|
+
@adapter.multiple_strings(keys).map do |name, data|
|
40
|
+
[name.gsub(impressions_metrics_key('count.'), ''), data]
|
41
|
+
end.to_h
|
42
|
+
end
|
43
|
+
|
44
|
+
def latencies
|
45
|
+
collected_latencies = {}
|
46
|
+
latencies_array = Array.new(BinarySearchLatencyTracker::BUCKETS.length, 0)
|
47
|
+
keys = @adapter.find_strings_by_prefix(impressions_metrics_key('latency'))
|
48
|
+
|
49
|
+
return [] if keys.empty?
|
50
|
+
|
51
|
+
found_latencies = @adapter.multiple_strings(keys).map do |name, data|
|
52
|
+
[name.gsub(impressions_metrics_key('latency.'), ''), data]
|
53
|
+
end.to_h
|
54
|
+
|
55
|
+
found_latencies.each do |key, value|
|
56
|
+
if key.start_with?('sdk.get_treatment')
|
57
|
+
index = key.gsub('sdk.get_treatment.', '').to_i
|
58
|
+
latencies_array[index] = value.to_i
|
59
|
+
|
60
|
+
next
|
61
|
+
end
|
62
|
+
|
63
|
+
collected_latencies[key] = value.split(',').map(&:to_f)
|
64
|
+
end
|
65
|
+
|
66
|
+
collected_latencies['sdk.get_treatment'] = latencies_array unless latencies_array.reduce(:+) == 0
|
67
|
+
|
68
|
+
collected_latencies
|
69
|
+
end
|
70
|
+
|
71
|
+
def gauges
|
72
|
+
# TODO
|
73
|
+
end
|
74
|
+
|
75
|
+
def clear_counts
|
76
|
+
keys = @adapter.find_strings_by_prefix(impressions_metrics_key('count'))
|
77
|
+
@adapter.delete(keys)
|
78
|
+
end
|
79
|
+
|
80
|
+
def clear_latencies
|
81
|
+
keys = @adapter.find_strings_by_prefix(impressions_metrics_key('latency'))
|
82
|
+
@adapter.delete(keys)
|
83
|
+
end
|
84
|
+
|
85
|
+
def clear_gauges
|
86
|
+
# TODO
|
87
|
+
end
|
88
|
+
|
89
|
+
def clear
|
90
|
+
clear_counts
|
91
|
+
clear_latencies
|
92
|
+
clear_gauges
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|