splitclient-rb 6.4.1.pre.rc1 → 6.4.1.pre.rc2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f474b8941f870d494de1e1c5314b2b880c12672cf9d46b17ceb902e99e85050a
4
- data.tar.gz: 27e00346829c95698a5e19acd95d392c9805a857cb5882ef0a94ff4011ea41d5
3
+ metadata.gz: 727fb19c1dbe097c79169ab3dceb79d3433f407e80c8fd5e2f6802dfb8f37690
4
+ data.tar.gz: 3b17876bc08c8d3e299dda5971331d44f1c157d3870775e1b965912f2669806c
5
5
  SHA512:
6
- metadata.gz: 9463b792568144eeec07f22bd3550ad5e3b626de832752694e67c82792f884c3627e0f1b1774a3cff6168c860dbf0b248873df6848db39f1b43f487600361956
7
- data.tar.gz: 8e2431113432f21f485ad67009c538bdfaba2902828e872099b2cf89e739bbbfae4c8114c20e49fa2e77357ed7cee9d0e524b341ca1d8667ba0607d6a5fd47f7
6
+ metadata.gz: 98d13f44e00258349853061336df8ccc775359c89ff95d3460a7f27e2a40027ba8e54d0b3a8f39a0f3cb1da38159ac49bda8d64e20c716b2604f269792a4ad5a
7
+ data.tar.gz: 9f47b928cbfd5eb6f6ce789f420b68bcc473e4668a6109428e7ad58faac8601b51adca9d5637a8a32411211067a28b6993c235dca684e39d2e59405798c2d450
@@ -84,6 +84,9 @@ require 'splitclient-rb/engine/models/treatment'
84
84
  require 'splitclient-rb/utilitites'
85
85
  require 'splitclient-rb/validators'
86
86
 
87
+ # redis metrics fixer
88
+ require 'splitclient-rb/redis_metrics_fixer'
89
+
87
90
  # C extension
88
91
  require 'murmurhash/murmurhash_mri'
89
92
 
@@ -56,10 +56,14 @@ module SplitIoClient
56
56
  end
57
57
 
58
58
  def find_strings_by_prefix(prefix)
59
+ find_strings_by_pattern("#{prefix}*")
60
+ end
61
+
62
+ def find_strings_by_pattern(pattern)
59
63
  memo = { items: [], cursor: 0 }
60
64
 
61
65
  loop do
62
- memo[:cursor], items = @redis.scan(memo[:cursor], match: "#{prefix}*", count: SCAN_SLICE)
66
+ memo[:cursor], items = @redis.scan(memo[:cursor], match: "#{pattern}", count: SCAN_SLICE)
63
67
 
64
68
  memo[:items].push(*items)
65
69
 
@@ -23,27 +23,14 @@ module SplitIoClient
23
23
  end
24
24
 
25
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 = (OPERATIONS.include?(operation)) ? build_latencies_for_op(operation, binary_search.add_latency_millis(time_in_ms, true)) : [time_in_ms]
29
- @latencies << { operation: operation, latencies: latencies_for_op }
26
+ if (OPERATIONS.include?(operation))
27
+ index = binary_search.add_latency_millis(time_in_ms, true)
28
+ increase_latency_bucket(operation, index)
30
29
  else
31
- (OPERATIONS.include?(operation)) ? increase_latencies_for_op(operation_hash[:latencies], binary_search.add_latency_millis(time_in_ms, true)) : operation_hash[:latencies].push(time_in_ms)
30
+ concatenate_latency(operation, time_in_ms)
32
31
  end
33
32
  end
34
33
 
35
- def build_latencies_for_op(operation, index)
36
- latencies_array = Array.new(BinarySearchLatencyTracker::BUCKETS.length, 0)
37
-
38
- latencies_array[index] = 1
39
-
40
- latencies_array
41
- end
42
-
43
- def increase_latencies_for_op(operation_latencies_array, index)
44
- operation_latencies_array[index] += 1
45
- end
46
-
47
34
  def add_gauge(gauge, value)
48
35
  gauge_hash = @gauges.find { |g| g[:name] == gauge }
49
36
  if gauge_hash.nil?
@@ -71,6 +58,10 @@ module SplitIoClient
71
58
  # TODO
72
59
  end
73
60
 
61
+ def fix_latencies
62
+ # NOOP
63
+ end
64
+
74
65
  def clear_counts
75
66
  @counts = []
76
67
  end
@@ -134,6 +125,34 @@ module SplitIoClient
134
125
  @value = 0
135
126
  end
136
127
  end
128
+
129
+ private
130
+
131
+ def increase_latency_bucket(operation, index)
132
+ operation_latencies = find_operation_latencies(operation)
133
+
134
+ if (operation_latencies.nil?)
135
+ latencies_array = Array.new(BinarySearchLatencyTracker::BUCKETS.length, 0)
136
+ latencies_array[index] = 1
137
+ @latencies << { operation: operation, latencies: latencies_array }
138
+ else
139
+ operation_latencies[:latencies][index] += 1
140
+ end
141
+ end
142
+
143
+ def concatenate_latency(operation, time_in_ms)
144
+ operation_latencies = find_operation_latencies(operation)
145
+
146
+ if (operation_latencies.nil?)
147
+ @latencies << { operation: operation, latencies: [time_in_ms] }
148
+ else
149
+ operation_latencies[:latencies].push(time_in_ms)
150
+ end
151
+ end
152
+
153
+ def find_operation_latencies(operation)
154
+ @latencies.find { |l| l[:operation] == operation }
155
+ end
137
156
  end
138
157
  end
139
158
  end
@@ -38,30 +38,16 @@ module SplitIoClient
38
38
  keys = @adapter.find_strings_by_prefix(impressions_metrics_key('latency'))
39
39
  return [] if keys.empty?
40
40
 
41
- found_latencies = @adapter.multiple_strings(keys).map do |name, data|
42
- [name.gsub(impressions_metrics_key('latency.'), ''), data]
43
- end.to_h
44
-
45
- collected_latencies = {}
46
-
47
- found_latencies.each do |key, value|
48
- operation, bucket = key.split('.bucket.')
49
- collected_latencies[operation] = {} unless collected_latencies[operation]
50
- collected_latencies[operation].merge!({bucket => value})
51
- end
52
-
53
- latencies = {}
41
+ collected_latencies = collect_latencies(keys)
54
42
 
55
- collected_latencies.keys.each do |operation|
56
- latencies_array = Array.new(BinarySearchLatencyTracker::BUCKETS.length, 0)
43
+ collected_latencies.keys.each_with_object({}) do |operation, latencies|
44
+ operation_latencies = Array.new(BinarySearchLatencyTracker::BUCKETS.length, 0)
57
45
  collected_latencies[operation].each do |bucket, value|
58
- latencies_array[bucket.to_i] = value.to_i
46
+ operation_latencies[bucket.to_i] = value.to_i
59
47
  end
60
48
 
61
- latencies[operation] = latencies_array
49
+ latencies[operation] = operation_latencies
62
50
  end
63
-
64
- latencies
65
51
  end
66
52
 
67
53
  def gauges
@@ -78,6 +64,35 @@ module SplitIoClient
78
64
  @adapter.delete(keys)
79
65
  end
80
66
 
67
+ # introduced to fix incorrect latencies
68
+ def fix_latencies
69
+ keys =[]
70
+
71
+ 23.times do |index|
72
+ keys.concat @adapter.find_strings_by_pattern(latencies_to_be_deleted_key_pattern_prefix("sdk.get_treatment.#{index}"))
73
+ end
74
+
75
+ keys.concat @adapter.find_strings_by_pattern(latencies_to_be_deleted_key_pattern_prefix('sdk.get_treatments'))
76
+ keys.concat @adapter.find_strings_by_pattern(latencies_to_be_deleted_key_pattern_prefix('sdk.get_treatment_with_config'))
77
+ keys.concat @adapter.find_strings_by_pattern(latencies_to_be_deleted_key_pattern_prefix('sdk.get_treatments_with_config'))
78
+
79
+ keys.concat @adapter.find_strings_by_pattern(latencies_to_be_deleted_key_pattern_prefix('*.time'))
80
+
81
+ SplitIoClient.configuration.logger.info("Found incorrect latency keys, deleting. Keys: #{keys}") unless keys.size == 0
82
+
83
+ keys.each_slice(500) do |chunk|
84
+ @adapter.pipelined do
85
+ chunk.each do |key|
86
+ @adapter.delete key
87
+ end
88
+ end
89
+ end
90
+ end
91
+
92
+ def latencies_to_be_deleted_key_pattern_prefix(key)
93
+ "#{SplitIoClient.configuration.redis_namespace}/#{SplitIoClient.configuration.language}-*/latency.#{key}"
94
+ end
95
+
81
96
  def clear_gauges
82
97
  # TODO
83
98
  end
@@ -87,6 +102,22 @@ module SplitIoClient
87
102
  clear_latencies
88
103
  clear_gauges
89
104
  end
105
+
106
+ private
107
+
108
+ def find_latencies(keys)
109
+ @adapter.multiple_strings(keys).map do |name, data|
110
+ [name.gsub(impressions_metrics_key('latency.'), ''), data]
111
+ end.to_h
112
+ end
113
+
114
+ def collect_latencies(keys)
115
+ find_latencies(keys).each_with_object({}) do |(key, value), collected_latencies|
116
+ operation, bucket = key.split('.bucket.')
117
+ collected_latencies[operation] = {} unless collected_latencies[operation]
118
+ collected_latencies[operation].merge!({bucket => value})
119
+ end
120
+ end
90
121
  end
91
122
  end
92
123
  end
@@ -5,7 +5,7 @@ module SplitIoClient
5
5
  class MetricsRepository < Repository
6
6
  extend Forwardable
7
7
  def_delegators :@adapter, :add_count, :add_latency, :add_gauge, :counts, :latencies, :gauges,
8
- :clear_counts, :clear_latencies, :clear_gauges, :clear
8
+ :clear_counts, :clear_latencies, :clear_gauges, :clear, :fix_latencies
9
9
 
10
10
  def initialize(adapter)
11
11
  @adapter = case adapter.class.to_s
@@ -0,0 +1,35 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SplitIoClient
4
+ class RedisMetricsFixer
5
+ def initialize(metrics_repository)
6
+ @metrics_repository = metrics_repository
7
+ end
8
+
9
+ def call
10
+ return if ENV['SPLITCLIENT_ENV'] == 'test' || SplitIoClient.configuration.mode == :standalone
11
+
12
+ fixer_thread
13
+
14
+ if defined?(PhusionPassenger)
15
+ PhusionPassenger.on_event(:starting_worker_process) do |forked|
16
+ fixer_thread if forked
17
+ end
18
+ end
19
+ end
20
+
21
+ private
22
+
23
+ def fixer_thread
24
+ Thread.new do
25
+ begin
26
+ SplitIoClient.configuration.logger.info('Starting redis metrics fixer')
27
+
28
+ @metrics_repository.fix_latencies
29
+ rescue StandardError => error
30
+ SplitIoClient.configuration.log_found_exception(__method__.to_s, error)
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
@@ -42,6 +42,8 @@ module SplitIoClient
42
42
 
43
43
  validate_api_key
44
44
 
45
+ RedisMetricsFixer.new(@metrics_repository).call
46
+
45
47
  @sdk_blocker.block if @sdk_blocker
46
48
  end
47
49
 
@@ -1,3 +1,3 @@
1
1
  module SplitIoClient
2
- VERSION = '6.4.1.pre.rc1'
2
+ VERSION = '6.4.1.pre.rc2'
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: splitclient-rb
3
3
  version: !ruby/object:Gem::Version
4
- version: 6.4.1.pre.rc1
4
+ version: 6.4.1.pre.rc2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Split Software
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-07-24 00:00:00.000000000 Z
11
+ date: 2019-07-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: allocation_stats
@@ -378,6 +378,7 @@ files:
378
378
  - lib/splitclient-rb/localhost_utils.rb
379
379
  - lib/splitclient-rb/managers/localhost_split_manager.rb
380
380
  - lib/splitclient-rb/managers/split_manager.rb
381
+ - lib/splitclient-rb/redis_metrics_fixer.rb
381
382
  - lib/splitclient-rb/split_config.rb
382
383
  - lib/splitclient-rb/split_factory.rb
383
384
  - lib/splitclient-rb/split_factory_builder.rb