splitclient-rb 3.1.0.pre.rc9 → 3.1.0.pre.rc10

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
  SHA1:
3
- metadata.gz: 3037157b7408479db6d29868df4005078bf344c4
4
- data.tar.gz: 20b2c1ef05f4ab0ea4114a748ef513e0b95fcf51
3
+ metadata.gz: 37a7aea4e576c0285c8fe0b52407263314b3dbe1
4
+ data.tar.gz: 0dfcf521a72a8eeac66bf8a1e2a4bcb45ab7b6be
5
5
  SHA512:
6
- metadata.gz: 8894fab929d077ee1ab8906e0326076944a0bb4de41514dc8672e6d0ec0e21ffc9dc3394d6d66367c611304e4d6f81a4c4b9442acff078444e0391e490dc4577
7
- data.tar.gz: '01656839c7ca92686ee5b0623de195ce42caa66673cc7873baf010b08d5e5c5b71b018f1f4d17b2997f3dae2f4a4ef7944e2df081a8596d22360861414fa55c6'
6
+ metadata.gz: 01234be503798df68a17b5ac3182736a446cfe4c35fdad405a719e33d748adc1158f312e591601082fd52a7cec543ae5b76de09b1aa383db16152d162095cd37
7
+ data.tar.gz: 8baf6f0b69c26309421282d9c331abb94eae269be202742fd308cf7df8941ff07fd5f1c0c3d85ade401e84025305ae2715f085de57c3d0aca8ec0142a10d3466
@@ -6,6 +6,8 @@ module SplitIoClient
6
6
  module Adapters
7
7
  # Redis adapter used to provide interface to Redis
8
8
  class RedisAdapter
9
+ attr_reader :redis
10
+
9
11
  def initialize(redis_url)
10
12
  connection = redis_url.is_a?(Hash) ? redis_url : { url: redis_url }
11
13
 
@@ -58,6 +60,10 @@ module SplitIoClient
58
60
  Hash[keys.zip(@redis.mget(keys))]
59
61
  end
60
62
 
63
+ def append_to_string(key, val)
64
+ @redis.append(key, val)
65
+ end
66
+
61
67
  # Bool
62
68
  def set_bool(key, val)
63
69
  @redis.set(key, val.to_s)
@@ -111,6 +117,10 @@ module SplitIoClient
111
117
 
112
118
  @redis.del(key)
113
119
  end
120
+
121
+ def inc(key, inc = 1)
122
+ @redis.incrby(key, inc)
123
+ end
114
124
  end
115
125
  end
116
126
  end
@@ -18,6 +18,12 @@ module SplitIoClient
18
18
  end
19
19
  end
20
20
 
21
+ def add_bulk(key, treatments, time)
22
+ treatments.each do |split_name, treatment|
23
+ add(split_name, 'key_name' => key, 'treatment' => treatment, 'time' => time)
24
+ end
25
+ end
26
+
21
27
  # Get everything from the queue and leave it empty
22
28
  def clear
23
29
  @adapter.clear
@@ -3,6 +3,8 @@ module SplitIoClient
3
3
  module Repositories
4
4
  module Impressions
5
5
  class RedisRepository < Repository
6
+ IMPRESSIONS_SLICE = 1000
7
+
6
8
  def initialize(adapter, config)
7
9
  @adapter = adapter
8
10
  @config = config
@@ -15,6 +17,16 @@ module SplitIoClient
15
17
  )
16
18
  end
17
19
 
20
+ def add_bulk(key, treatments, time)
21
+ @adapter.redis.pipelined do
22
+ treatments.each_slice(IMPRESSIONS_SLICE) do |treatments_slice|
23
+ treatments_slice.each do |split_name, treatment|
24
+ add(split_name, 'key_name' => key, 'treatment' => treatment, 'time' => time)
25
+ end
26
+ end
27
+ end
28
+ end
29
+
18
30
  # Get random impressions from redis in batches of size @config.impressions_queue_size,
19
31
  # delete fetched impressions afterwards
20
32
  def clear
@@ -4,7 +4,7 @@ module SplitIoClient
4
4
  # Repository which forwards impressions interface to the selected adapter
5
5
  class ImpressionsRepository < Repository
6
6
  extend Forwardable
7
- def_delegators :@adapter, :add, :clear, :empty?
7
+ def_delegators :@adapter, :add, :add_bulk, :clear, :empty?
8
8
 
9
9
  def initialize(adapter, config)
10
10
  @adapter = case adapter.class.to_s
@@ -0,0 +1,123 @@
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
+ #
75
+ # small class to act as DTO for counts
76
+ #
77
+ class SumAndCount
78
+ attr_reader :count
79
+ attr_reader :sum
80
+
81
+ def initialize
82
+ @count = 0
83
+ @sum = 0
84
+ end
85
+
86
+ def add_delta(delta)
87
+ @count += 1
88
+ @sum += delta
89
+ end
90
+
91
+ def clear
92
+ @count = 0
93
+ @sum = 0
94
+ end
95
+ end
96
+
97
+ #
98
+ # small class to act as DTO for gauges
99
+ #
100
+ class ValueAndCount
101
+ attr_reader :count
102
+ attr_reader :value
103
+
104
+ def initialize
105
+ @count = 0
106
+ @value = 0
107
+ end
108
+
109
+ def set_value(value)
110
+ @count += 1
111
+ @value = value
112
+ end
113
+
114
+ def clear
115
+ @count = 0
116
+ @value = 0
117
+ end
118
+ end
119
+ end
120
+ end
121
+ end
122
+ end
123
+ end
@@ -0,0 +1,92 @@
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 = namespace_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 = namespace_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(namespace_key('count'))
36
+
37
+ return [] if keys.empty?
38
+
39
+ @adapter.multiple_strings(keys).map do |name, data|
40
+ [name.gsub(namespace_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(namespace_key('latency'))
48
+
49
+ return [] if keys.empty?
50
+
51
+ found_latencies = @adapter.multiple_strings(keys).map do |name, data|
52
+ [name.gsub(namespace_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
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(namespace_key('count'))
77
+ @adapter.delete(keys)
78
+ end
79
+
80
+ def clear_latencies
81
+ keys = @adapter.find_strings_by_prefix(namespace_key('latency'))
82
+ @adapter.delete(keys)
83
+ end
84
+
85
+ def clear_gauges
86
+ # TODO
87
+ end
88
+ end
89
+ end
90
+ end
91
+ end
92
+ 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 MetricsRepository < Repository
6
+ extend Forwardable
7
+ def_delegators :@adapter, :add_count, :add_latency, :add_gauge, :counts, :latencies, :gauges,
8
+ :clear_counts, :clear_latencies, :clear_gauges
9
+
10
+ def initialize(adapter, config)
11
+ @adapter = case adapter.class.to_s
12
+ when 'SplitIoClient::Cache::Adapters::MemoryAdapter'
13
+ Repositories::Metrics::MemoryRepository.new(adapter, config)
14
+ when 'SplitIoClient::Cache::Adapters::RedisAdapter'
15
+ Repositories::Metrics::RedisRepository.new(adapter, config)
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
@@ -52,16 +52,22 @@ module SplitIoClient
52
52
  # Increment the internal counter for the bucket this latency falls into.
53
53
  # @param millis
54
54
  #
55
- def add_latency_millis(millis)
55
+ def add_latency_millis(millis, return_index = false)
56
56
  index = find_bucket_index(millis * 1000)
57
+
58
+ return index if return_index
59
+
57
60
  @latencies[index] += 1
58
61
  @latencies
59
62
  end
60
63
 
61
64
  # Increment the internal counter for the bucket this latency falls into.
62
65
  # @param micros
63
- def add_latency_micros(micros)
66
+ def add_latency_micros(micros, return_index = false)
64
67
  index = find_bucket_index(micros)
68
+
69
+ return index if return_index
70
+
65
71
  @latencies[index] += 1
66
72
  @latencies
67
73
  end
@@ -32,12 +32,13 @@ module SplitIoClient
32
32
  # @return [int] queue size
33
33
  attr_accessor :queue_size
34
34
 
35
- def initialize(queue_size)
36
- @latencies = []
37
- @counts = []
38
- @gauges = []
35
+ def initialize(queue_size, config, repository)
39
36
  @queue_size = queue_size
40
37
  @binary_search = SplitIoClient::BinarySearchLatencyTracker.new
38
+
39
+ @config = config
40
+
41
+ @repository = repository
41
42
  end
42
43
 
43
44
  #
@@ -48,18 +49,9 @@ module SplitIoClient
48
49
  #
49
50
  # @return void
50
51
  def count(counter, delta)
51
- return if delta <= 0
52
+ return if (delta <= 0) || counter.nil? || counter.strip.empty?
52
53
 
53
- return if (counter.nil? || counter.strip.empty?)
54
-
55
- counter_hash = @counts.find { |c| c[:name] == counter }
56
- if counter_hash.nil?
57
- counter_delta = SumAndCount.new
58
- counter_delta.add_delta(delta)
59
- @counts << {name: counter, delta: counter_delta}
60
- else
61
- counter_hash[:delta].add_delta(delta)
62
- end
54
+ @repository.add_count(counter, delta)
63
55
  end
64
56
 
65
57
  #
@@ -70,18 +62,9 @@ module SplitIoClient
70
62
  #
71
63
  # @return void
72
64
  def time(operation, time_in_ms)
65
+ return if operation.nil? || operation.empty? || time_in_ms < 0
73
66
 
74
- if operation.nil? || operation.empty? || time_in_ms < 0
75
- return;
76
- end
77
-
78
- operation_hash = @latencies.find { |l| l[:operation] == operation }
79
- if operation_hash.nil?
80
- latencies_for_op = (operation == 'sdk.get_treatment') ? @binary_search.add_latency_millis(time_in_ms) : [time_in_ms]
81
- @latencies << {operation: operation, latencies: latencies_for_op}
82
- else
83
- latencies_for_op = (operation == 'sdk.get_treatment') ? @binary_search.add_latency_millis(time_in_ms) : operation_hash[:latencies].push(time_in_ms)
84
- end
67
+ @repository.add_latency(operation, time_in_ms, @binary_search)
85
68
  end
86
69
 
87
70
  #
@@ -92,67 +75,9 @@ module SplitIoClient
92
75
  #
93
76
  # @return void
94
77
  def gauge(gauge, value)
95
- if gauge.nil? || gauge.empty?
96
- return
97
- end
78
+ return if gauge.nil? || gauge.empty?
98
79
 
99
- gauge_hash = @gauges.find { |g| g[:name] == gauge }
100
- if gauge_hash.nil?
101
- gauge_value = ValueAndCount.new
102
- gauge_value.set_value(value)
103
- @gauges << {name: gauge, value: gauge_value}
104
- else
105
- gauge_hash[:value].set_value(value)
106
- end
80
+ @repository.add_gauge(gauge, value)
107
81
  end
108
-
109
82
  end
110
-
111
- #
112
- # small class to act as DTO for counts
113
- #
114
- class SumAndCount
115
- attr_reader :count
116
- attr_reader :sum
117
-
118
- def initialize
119
- @count = 0
120
- @sum = 0
121
- end
122
-
123
- def add_delta(delta)
124
- @count++
125
- @sum += delta
126
- end
127
-
128
- def clear
129
- @count = 0
130
- @sum = 0
131
- end
132
- end
133
-
134
- #
135
- # small class to act as DTO for gauges
136
- #
137
- class ValueAndCount
138
- attr_reader :count
139
- attr_reader :value
140
-
141
- def initialize
142
- @count = 0
143
- @value = 0
144
- end
145
-
146
- def set_value(value)
147
- @count += 1
148
- @value = value
149
- end
150
-
151
- def clear
152
- @count = 0
153
- @value = 0
154
- end
155
-
156
- end
157
-
158
83
  end
@@ -35,14 +35,16 @@ module SplitIoClient
35
35
  # @param api_key [String] the API key for your split account
36
36
  #
37
37
  # @return [SplitIoClient] split.io client instance
38
- def initialize(api_key, config, splits_repository, segments_repository, impressions_repository, sdk_blocker)
38
+ def initialize(api_key, config, splits_repository, segments_repository, impressions_repository, metrics_repository, sdk_blocker)
39
39
  @api_key = api_key
40
40
  @config = config
41
- @metrics = Metrics.new(100)
42
41
 
43
42
  @splits_repository = splits_repository
44
43
  @segments_repository = segments_repository
45
44
  @impressions_repository = impressions_repository
45
+ @metrics_repository = metrics_repository
46
+
47
+ @metrics = Metrics.new(100, @config, @metrics_repository)
46
48
 
47
49
  @sdk_blocker = sdk_blocker
48
50
 
@@ -62,11 +64,12 @@ module SplitIoClient
62
64
  metrics_sender
63
65
  impressions_sender
64
66
  when :consumer
65
- metrics_sender
67
+ # Do nothing in background
66
68
  when :producer
67
69
  split_store
68
70
  segment_store
69
71
  impressions_sender
72
+ metrics_sender
70
73
 
71
74
  sleep unless ENV['SPLITCLIENT_ENV'] == 'test'
72
75
  end
@@ -248,53 +251,35 @@ module SplitIoClient
248
251
  #
249
252
  # @return [void]
250
253
  def post_metrics
251
- if @metrics.latencies.empty?
254
+ if @metrics_repository.latencies.empty?
252
255
  @config.logger.debug('No latencies to report.') if @config.debug_enabled
253
256
  else
254
- @metrics.latencies.each do |l|
255
- metrics_time = {}
256
- metrics_time = {name: l[:operation], latencies: l[:latencies]}
257
+ @metrics_repository.latencies.each do |name, latencies|
258
+ metrics_time = { name: name, latencies: latencies }
257
259
  res = post_api('/metrics/time', metrics_time)
258
260
  if res.status / 100 != 2
259
261
  @config.logger.error("Unexpected status code while posting time metrics: #{res.status}")
260
262
  else
261
- @config.logger.debug("Metric time reported: #{metrics_time.size()}") if @config.debug_enabled
263
+ @config.logger.debug("Metric time reported: #{metrics_time.size}") if @config.debug_enabled
262
264
  end
263
265
  end
264
266
  end
265
- @metrics.latencies.clear
267
+ @metrics_repository.clear_latencies
266
268
 
267
- if @metrics.counts.empty?
269
+ if @metrics_repository.counts.empty?
268
270
  @config.logger.debug('No counts to report.') if @config.debug_enabled
269
271
  else
270
- @metrics.counts.each do |c|
271
- metrics_count = {}
272
- metrics_count = {name: c[:name], delta: c[:delta].sum}
272
+ @metrics_repository.counts.each do |name, count|
273
+ metrics_count = { name: name, delta: count }
273
274
  res = post_api('/metrics/counter', metrics_count)
274
275
  if res.status / 100 != 2
275
276
  @config.logger.error("Unexpected status code while posting count metrics: #{res.status}")
276
277
  else
277
- @config.logger.debug("Metric counts reported: #{metrics_count.size()}") if @config.debug_enabled
278
- end
279
- end
280
- end
281
- @metrics.counts.clear
282
-
283
- if @metrics.gauges.empty?
284
- @config.logger.debug('No gauges to report.') if @config.debug_enabled
285
- else
286
- @metrics.gauges.each do |g|
287
- metrics_gauge = {}
288
- metrics_gauge = {name: g[:name], value: g[:gauge].value}
289
- res = post_api('/metrics/gauge', metrics_gauge)
290
- if res.status / 100 != 2
291
- @config.logger.error("Unexpected status code while posting gauge metrics: #{res.status}")
292
- else
293
- @config.logger.debug("Metric gauge reported: #{metrics_gauge.size()}") if @config.debug_enabled
278
+ @config.logger.debug("Metric counts reported: #{metrics_count.size}") if @config.debug_enabled
294
279
  end
295
280
  end
296
281
  end
297
- @metrics.gauges.clear
282
+ @metrics_repository.clear_counts
298
283
  end
299
284
 
300
285
  private
@@ -15,6 +15,9 @@ require 'cache/repositories/splits_repository'
15
15
  require 'cache/repositories/impressions_repository'
16
16
  require 'cache/repositories/impressions/memory_repository'
17
17
  require 'cache/repositories/impressions/redis_repository'
18
+ require 'cache/repositories/metrics_repository'
19
+ require 'cache/repositories/metrics/memory_repository'
20
+ require 'cache/repositories/metrics/redis_repository'
18
21
  require 'cache/stores/sdk_blocker'
19
22
  require 'cache/stores/segment_store'
20
23
  require 'cache/stores/split_store'
@@ -44,6 +44,10 @@ module SplitIoClient
44
44
  opts[:cache_adapter] || SplitConfig.default_cache_adapter, :sized_queue_adapter, @redis_url, @impressions_queue_size
45
45
  )
46
46
 
47
+ @metrics_adapter = SplitConfig.init_cache_adapter(
48
+ opts[:cache_adapter] || SplitConfig.default_cache_adapter, :map_adapter, @redis_url, false
49
+ )
50
+
47
51
  @logger = opts[:logger] || SplitConfig.default_logger
48
52
  @debug_enabled = opts[:debug_enabled] || SplitConfig.default_debug
49
53
  @transport_debug_enabled = opts[:transport_debug_enabled] || SplitConfig.default_debug
@@ -89,6 +93,12 @@ module SplitIoClient
89
93
  # @return [Object] Impressions adapter instance
90
94
  attr_reader :impressions_adapter
91
95
 
96
+ #
97
+ # The cache adapter to store metrics in
98
+ #
99
+ # @return [Symbol] Metrics adapter
100
+ attr_reader :metrics_adapter
101
+
92
102
  #
93
103
  # The connection timeout for network connections in seconds.
94
104
  #
@@ -179,6 +189,10 @@ module SplitIoClient
179
189
  :memory
180
190
  end
181
191
 
192
+ def self.default_metrics_adapter
193
+ :memory
194
+ end
195
+
182
196
  #
183
197
  # The default read timeout value
184
198
  #
@@ -131,7 +131,7 @@ module SplitIoClient
131
131
  # @param api_key [String] the API key for your split account
132
132
  #
133
133
  # @return [SplitIoClient] split.io client instance
134
- def initialize(api_key, config = {}, adapter = nil, localhost_mode = false, splits_repository, segments_repository, impressions_repository)
134
+ def initialize(api_key, config = {}, adapter = nil, localhost_mode = false, splits_repository, segments_repository, impressions_repository, metrics_repository)
135
135
  @localhost_mode = localhost_mode
136
136
  @localhost_mode_features = []
137
137
 
@@ -140,6 +140,7 @@ module SplitIoClient
140
140
  @splits_repository = splits_repository
141
141
  @segments_repository = segments_repository
142
142
  @impressions_repository = impressions_repository
143
+ @metrics_repository = metrics_repository
143
144
 
144
145
  if api_key == LOCALHOST_MODE
145
146
  @localhost_mode = true
@@ -150,17 +151,23 @@ module SplitIoClient
150
151
  end
151
152
 
152
153
  def get_treatments(key, split_names, attributes = nil)
153
-
154
154
  # This localhost behavior must live in in localhost_spit_factory#client
155
155
  if is_localhost_mode?
156
- return split_names.each_with_object({}) do | (name), memo|
156
+ return split_names.each_with_object({}) do |name, memo|
157
157
  memo.merge!(name => get_localhost_treatment(name))
158
158
  end
159
159
  end
160
160
 
161
- @splits_repository.get_splits(split_names).each_with_object({}) do |(name, data), memo|
162
- memo.merge!(name => get_treatment(key, name, attributes, data))
161
+ bucketing_key, matching_key = keys_from_key(key)
162
+ bucketing_key = matching_key if bucketing_key.nil?
163
+
164
+ treatments = @splits_repository.get_splits(split_names).each_with_object({}) do |(name, data), memo|
165
+ memo.merge!(name => get_treatment(matching_key, name, attributes, data, false))
163
166
  end
167
+
168
+ @impressions_repository.add_bulk(matching_key, treatments, (Time.now.to_f * 1000.0).to_i)
169
+
170
+ treatments
164
171
  end
165
172
 
166
173
  #
@@ -170,7 +177,7 @@ module SplitIoClient
170
177
  # @param split_name [String/Array] name of the feature that is being validated or array of them
171
178
  #
172
179
  # @return [String/Hash] Treatment as String or Hash of treatments in case of array of features
173
- def get_treatment(key, split_name, attributes = nil, split_data = nil)
180
+ def get_treatment(key, split_name, attributes = nil, split_data = nil, store_impressions = true)
174
181
  bucketing_key, matching_key = keys_from_key(key)
175
182
  bucketing_key = matching_key if bucketing_key.nil?
176
183
 
@@ -208,7 +215,7 @@ module SplitIoClient
208
215
 
209
216
  begin
210
217
  latency = (Time.now - start) * 1000.0
211
- if @config.impressions_queue_size > 0
218
+ if @config.impressions_queue_size > 0 && store_impressions
212
219
  # Disable impressions if @config.impressions_queue_size == -1
213
220
  @impressions_repository.add(split_name, 'key_name' => matching_key, 'treatment' => result, 'time' => (Time.now.to_f * 1000.0).to_i)
214
221
  end
@@ -288,9 +295,10 @@ module SplitIoClient
288
295
  @splits_repository = SplitIoClient::Cache::Repositories::SplitsRepository.new(@cache_adapter)
289
296
  @segments_repository = SplitIoClient::Cache::Repositories::SegmentsRepository.new(@cache_adapter)
290
297
  @impressions_repository = SplitIoClient::Cache::Repositories::ImpressionsRepository.new(@config.impressions_adapter, @config)
298
+ @metrics_repository = SplitIoClient::Cache::Repositories::MetricsRepository.new(@config.metrics_adapter, @config)
291
299
  @sdk_blocker = SplitIoClient::Cache::Stores::SDKBlocker.new(@config)
292
300
  @adapter = api_key != 'localhost' \
293
- ? SplitAdapter.new(api_key, @config, @splits_repository, @segments_repository, @impressions_repository, @sdk_blocker)
301
+ ? SplitAdapter.new(api_key, @config, @splits_repository, @segments_repository, @impressions_repository, @metrics_repository, @sdk_blocker)
294
302
  : nil
295
303
  @localhost_mode = api_key == 'localhost'
296
304
 
@@ -317,7 +325,7 @@ module SplitIoClient
317
325
  attr_reader :adapter
318
326
 
319
327
  def init_client
320
- SplitClient.new(@api_key, @config, @adapter, @localhost_mode, @splits_repository, @segments_repository, @impressions_repository)
328
+ SplitClient.new(@api_key, @config, @adapter, @localhost_mode, @splits_repository, @segments_repository, @impressions_repository, @metrics_repository)
321
329
  end
322
330
 
323
331
  def init_manager
@@ -1,3 +1,3 @@
1
1
  module SplitIoClient
2
- VERSION = '3.1.0-rc9'
2
+ VERSION = '3.1.0-rc10'
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: 3.1.0.pre.rc9
4
+ version: 3.1.0.pre.rc10
5
5
  platform: ruby
6
6
  authors:
7
7
  - Split Software
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2016-11-04 00:00:00.000000000 Z
11
+ date: 2016-11-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -257,6 +257,9 @@ files:
257
257
  - lib/cache/repositories/impressions/memory_repository.rb
258
258
  - lib/cache/repositories/impressions/redis_repository.rb
259
259
  - lib/cache/repositories/impressions_repository.rb
260
+ - lib/cache/repositories/metrics/memory_repository.rb
261
+ - lib/cache/repositories/metrics/redis_repository.rb
262
+ - lib/cache/repositories/metrics_repository.rb
260
263
  - lib/cache/repositories/repository.rb
261
264
  - lib/cache/repositories/segments_repository.rb
262
265
  - lib/cache/repositories/splits_repository.rb