splitclient-rb 7.2.2.pre.rc1-java → 7.3.0.pre.rc2-java

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (69) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +15 -0
  3. data/CHANGES.txt +6 -0
  4. data/lib/splitclient-rb.rb +24 -9
  5. data/lib/splitclient-rb/cache/adapters/redis_adapter.rb +4 -0
  6. data/lib/splitclient-rb/cache/fetchers/segment_fetcher.rb +21 -9
  7. data/lib/splitclient-rb/cache/fetchers/split_fetcher.rb +9 -9
  8. data/lib/splitclient-rb/cache/repositories/events/memory_repository.rb +6 -3
  9. data/lib/splitclient-rb/cache/repositories/events_repository.rb +4 -3
  10. data/lib/splitclient-rb/cache/repositories/impressions/memory_repository.rb +8 -0
  11. data/lib/splitclient-rb/cache/repositories/impressions/redis_repository.rb +2 -0
  12. data/lib/splitclient-rb/cache/repositories/repository.rb +0 -4
  13. data/lib/splitclient-rb/cache/repositories/segments_repository.rb +20 -0
  14. data/lib/splitclient-rb/cache/repositories/splits_repository.rb +4 -0
  15. data/lib/splitclient-rb/cache/senders/localhost_repo_cleaner.rb +1 -3
  16. data/lib/splitclient-rb/cache/stores/sdk_blocker.rb +9 -0
  17. data/lib/splitclient-rb/clients/split_client.rb +59 -25
  18. data/lib/splitclient-rb/constants.rb +6 -1
  19. data/lib/splitclient-rb/engine/api/client.rb +3 -2
  20. data/lib/splitclient-rb/engine/api/events.rb +10 -1
  21. data/lib/splitclient-rb/engine/api/impressions.rb +19 -2
  22. data/lib/splitclient-rb/engine/api/segments.rb +20 -18
  23. data/lib/splitclient-rb/engine/api/splits.rb +10 -10
  24. data/lib/splitclient-rb/engine/api/telemetry_api.rb +39 -0
  25. data/lib/splitclient-rb/engine/auth_api_client.rb +21 -8
  26. data/lib/splitclient-rb/engine/common/impressions_manager.rb +27 -3
  27. data/lib/splitclient-rb/engine/metrics/binary_search_latency_tracker.rb +3 -65
  28. data/lib/splitclient-rb/engine/push_manager.rb +12 -3
  29. data/lib/splitclient-rb/engine/sync_manager.rb +85 -46
  30. data/lib/splitclient-rb/engine/synchronizer.rb +14 -22
  31. data/lib/splitclient-rb/split_config.rb +46 -21
  32. data/lib/splitclient-rb/split_factory.rb +31 -13
  33. data/lib/splitclient-rb/split_factory_registry.rb +12 -0
  34. data/lib/splitclient-rb/sse/event_source/client.rb +53 -28
  35. data/lib/splitclient-rb/sse/event_source/event_parser.rb +10 -1
  36. data/lib/splitclient-rb/sse/notification_manager_keeper.rb +45 -26
  37. data/lib/splitclient-rb/sse/sse_handler.rb +16 -21
  38. data/lib/splitclient-rb/sse/workers/segments_worker.rb +5 -4
  39. data/lib/splitclient-rb/sse/workers/splits_worker.rb +6 -3
  40. data/lib/splitclient-rb/telemetry/domain/constants.rb +42 -0
  41. data/lib/splitclient-rb/telemetry/domain/structs.rb +31 -0
  42. data/lib/splitclient-rb/telemetry/evaluation_consumer.rb +14 -0
  43. data/lib/splitclient-rb/telemetry/evaluation_producer.rb +21 -0
  44. data/lib/splitclient-rb/telemetry/init_consumer.rb +14 -0
  45. data/lib/splitclient-rb/telemetry/init_producer.rb +19 -0
  46. data/lib/splitclient-rb/telemetry/memory/memory_evaluation_consumer.rb +32 -0
  47. data/lib/splitclient-rb/telemetry/memory/memory_evaluation_producer.rb +24 -0
  48. data/lib/splitclient-rb/telemetry/memory/memory_init_consumer.rb +28 -0
  49. data/lib/splitclient-rb/telemetry/memory/memory_init_producer.rb +34 -0
  50. data/lib/splitclient-rb/telemetry/memory/memory_runtime_consumer.rb +112 -0
  51. data/lib/splitclient-rb/telemetry/memory/memory_runtime_producer.rb +81 -0
  52. data/lib/splitclient-rb/telemetry/memory/memory_synchronizer.rb +192 -0
  53. data/lib/splitclient-rb/telemetry/redis/redis_evaluation_producer.rb +38 -0
  54. data/lib/splitclient-rb/telemetry/redis/redis_init_producer.rb +37 -0
  55. data/lib/splitclient-rb/telemetry/redis/redis_synchronizer.rb +28 -0
  56. data/lib/splitclient-rb/telemetry/runtime_consumer.rb +24 -0
  57. data/lib/splitclient-rb/telemetry/runtime_producer.rb +24 -0
  58. data/lib/splitclient-rb/telemetry/storages/memory.rb +139 -0
  59. data/lib/splitclient-rb/telemetry/sync_task.rb +38 -0
  60. data/lib/splitclient-rb/telemetry/synchronizer.rb +29 -0
  61. data/lib/splitclient-rb/version.rb +1 -1
  62. metadata +24 -9
  63. data/lib/splitclient-rb/cache/repositories/metrics/memory_repository.rb +0 -163
  64. data/lib/splitclient-rb/cache/repositories/metrics/redis_repository.rb +0 -131
  65. data/lib/splitclient-rb/cache/repositories/metrics_repository.rb +0 -23
  66. data/lib/splitclient-rb/cache/senders/metrics_sender.rb +0 -55
  67. data/lib/splitclient-rb/engine/api/metrics.rb +0 -61
  68. data/lib/splitclient-rb/engine/metrics/metrics.rb +0 -80
  69. data/lib/splitclient-rb/redis_metrics_fixer.rb +0 -36
@@ -11,6 +11,7 @@ module SplitIoClient
11
11
  @splits_repository = splits_repository
12
12
  @segments_repository = segments_repository
13
13
  @config = config
14
+ @internal_ready = Concurrent::CountDownLatch.new(1)
14
15
 
15
16
  if @config.standalone?
16
17
  @splits_repository.not_ready!
@@ -49,6 +50,14 @@ module SplitIoClient
49
50
  return true if @config.consumer?
50
51
  @splits_repository.ready? && @segments_repository.ready?
51
52
  end
53
+
54
+ def sdk_internal_ready
55
+ @internal_ready.count_down
56
+ end
57
+
58
+ def wait_unitil_internal_ready
59
+ @internal_ready.wait
60
+ end
52
61
  end
53
62
  end
54
63
  end
@@ -1,6 +1,11 @@
1
1
  module SplitIoClient
2
2
  EVENTS_SIZE_THRESHOLD = 32768
3
3
  EVENT_AVERAGE_SIZE = 1024
4
+ GET_TREATMENT = 'get_treatment'
5
+ GET_TREATMENTS = 'get_treatments'
6
+ GET_TREATMENT_WITH_CONFIG = 'get_treatment_with_config'
7
+ GET_TREATMENTS_WITH_CONFIG = 'get_treatments_with_config'
8
+ TRACK = 'track'
4
9
 
5
10
  class SplitClient
6
11
  #
@@ -9,18 +14,17 @@ module SplitIoClient
9
14
  # @param api_key [String] the API key for your split account
10
15
  #
11
16
  # @return [SplitIoClient] split.io client instance
12
- def initialize(api_key, metrics, splits_repository, segments_repository, impressions_repository, metrics_repository, events_repository, sdk_blocker, config, impressions_manager)
17
+ def initialize(api_key, repositories, sdk_blocker, config, impressions_manager, telemetry_evaluation_producer)
13
18
  @api_key = api_key
14
- @metrics = metrics
15
- @splits_repository = splits_repository
16
- @segments_repository = segments_repository
17
- @impressions_repository = impressions_repository
18
- @metrics_repository = metrics_repository
19
- @events_repository = events_repository
19
+ @splits_repository = repositories[:splits]
20
+ @segments_repository = repositories[:segments]
21
+ @impressions_repository = repositories[:impressions]
22
+ @events_repository = repositories[:events]
20
23
  @sdk_blocker = sdk_blocker
21
24
  @destroyed = false
22
25
  @config = config
23
26
  @impressions_manager = impressions_manager
27
+ @telemetry_evaluation_producer = telemetry_evaluation_producer
24
28
  end
25
29
 
26
30
  def get_treatment(
@@ -28,7 +32,7 @@ module SplitIoClient
28
32
  multiple = false, evaluator = nil
29
33
  )
30
34
  impressions = []
31
- result = treatment(key, split_name, attributes, split_data, store_impressions, multiple, evaluator, 'get_treatment', impressions)
35
+ result = treatment(key, split_name, attributes, split_data, store_impressions, multiple, evaluator, GET_TREATMENT, impressions)
32
36
  @impressions_manager.track(impressions)
33
37
 
34
38
  if multiple
@@ -43,7 +47,7 @@ module SplitIoClient
43
47
  multiple = false, evaluator = nil
44
48
  )
45
49
  impressions = []
46
- result = treatment(key, split_name, attributes, split_data, store_impressions, multiple, evaluator, 'get_treatment_with_config', impressions)
50
+ result = treatment(key, split_name, attributes, split_data, store_impressions, multiple, evaluator, GET_TREATMENT_WITH_CONFIG, impressions)
47
51
  @impressions_manager.track(impressions)
48
52
 
49
53
  result
@@ -58,7 +62,7 @@ module SplitIoClient
58
62
  end
59
63
 
60
64
  def get_treatments_with_config(key, split_names, attributes = {})
61
- treatments(key, split_names, attributes,'get_treatments_with_config')
65
+ treatments(key, split_names, attributes, GET_TREATMENTS_WITH_CONFIG)
62
66
  end
63
67
 
64
68
  def destroy
@@ -85,6 +89,7 @@ module SplitIoClient
85
89
  def track(key, traffic_type_name, event_type, value = nil, properties = nil)
86
90
  return false unless valid_client && @config.split_validator.valid_track_parameters(key, traffic_type_name, event_type, value, properties)
87
91
 
92
+ start = Time.now
88
93
  properties_size = EVENT_AVERAGE_SIZE
89
94
 
90
95
  if !properties.nil?
@@ -102,13 +107,14 @@ module SplitIoClient
102
107
  'your events to a valid traffic type defined in the Split console')
103
108
  end
104
109
 
105
- begin
106
- @events_repository.add(key.to_s, traffic_type_name.downcase, event_type.to_s, (Time.now.to_f * 1000).to_i, value, properties, properties_size)
107
- true
108
- rescue StandardError => error
109
- @config.log_found_exception(__method__.to_s, error)
110
- false
111
- end
110
+ @events_repository.add(key.to_s, traffic_type_name.downcase, event_type.to_s, (Time.now.to_f * 1000).to_i, value, properties, properties_size)
111
+ record_latency(TRACK, start)
112
+ true
113
+ rescue StandardError => error
114
+ @config.log_found_exception(__method__.to_s, error)
115
+ record_exception(TRACK)
116
+
117
+ false
112
118
  end
113
119
 
114
120
  def keys_from_key(key)
@@ -209,10 +215,8 @@ module SplitIoClient
209
215
  @splits_repository.get_splits(sanitized_split_names).each_with_object({}) do |(name, data), memo|
210
216
  memo.merge!(name => treatment(key, name, attributes, data, false, true, evaluator, calling_method, impressions))
211
217
  end
212
- latency = (Time.now - start) * 1000.0
213
- # Measure
214
- @metrics.time('sdk.' + calling_method, latency)
215
218
 
219
+ record_latency(calling_method, start)
216
220
  @impressions_manager.track(impressions)
217
221
 
218
222
  split_names_keys = treatments_labels_change_numbers.keys
@@ -283,17 +287,15 @@ module SplitIoClient
283
287
  control_treatment.merge({ label: Engine::Models::Label::NOT_READY })
284
288
  end
285
289
 
286
- latency = (Time.now - start) * 1000.0
290
+ record_latency(calling_method, start) unless multiple
287
291
 
288
292
  impression = @impressions_manager.build_impression(matching_key, bucketing_key, split_name, treatment_data, { attributes: attributes, time: nil })
289
293
  impressions << impression unless impression.nil?
290
-
291
- # Measure
292
- @metrics.time('sdk.' + calling_method, latency) unless multiple
293
294
  rescue StandardError => error
294
- p error
295
295
  @config.log_found_exception(__method__.to_s, error)
296
296
 
297
+ record_exception(calling_method)
298
+
297
299
  impression = @impressions_manager.build_impression(matching_key, bucketing_key, split_name, control_treatment, { attributes: attributes, time: nil })
298
300
  impressions << impression unless impression.nil?
299
301
 
@@ -315,5 +317,37 @@ module SplitIoClient
315
317
  def parsed_attributes(attributes)
316
318
  return attributes || attributes.to_h
317
319
  end
320
+
321
+ def record_latency(method, start)
322
+ bucket = BinarySearchLatencyTracker.get_bucket((Time.now - start) * 1000.0)
323
+
324
+ case method
325
+ when GET_TREATMENT
326
+ @telemetry_evaluation_producer.record_latency(Telemetry::Domain::Constants::TREATMENT, bucket)
327
+ when GET_TREATMENTS
328
+ @telemetry_evaluation_producer.record_latency(Telemetry::Domain::Constants::TREATMENTS, bucket)
329
+ when GET_TREATMENT_WITH_CONFIG
330
+ @telemetry_evaluation_producer.record_latency(Telemetry::Domain::Constants::TREATMENT_WITH_CONFIG, bucket)
331
+ when GET_TREATMENTS_WITH_CONFIG
332
+ @telemetry_evaluation_producer.record_latency(Telemetry::Domain::Constants::TREATMENTS_WITH_CONFIG, bucket)
333
+ when TRACK
334
+ @telemetry_evaluation_producer.record_latency(Telemetry::Domain::Constants::TRACK, bucket)
335
+ end
336
+ end
337
+
338
+ def record_exception(method)
339
+ case method
340
+ when GET_TREATMENT
341
+ @telemetry_evaluation_producer.record_exception(Telemetry::Domain::Constants::TREATMENT)
342
+ when GET_TREATMENTS
343
+ @telemetry_evaluation_producer.record_exception(Telemetry::Domain::Constants::TREATMENTS)
344
+ when GET_TREATMENT_WITH_CONFIG
345
+ @telemetry_evaluation_producer.record_exception(Telemetry::Domain::Constants::TREATMENT_WITH_CONFIG)
346
+ when GET_TREATMENTS_WITH_CONFIG
347
+ @telemetry_evaluation_producer.record_exception(Telemetry::Domain::Constants::TREATMENTS_WITH_CONFIG)
348
+ when TRACK
349
+ @telemetry_evaluation_producer.record_exception(Telemetry::Domain::Constants::TRACK)
350
+ end
351
+ end
318
352
  end
319
353
  end
@@ -6,5 +6,10 @@ class SplitIoClient::Constants
6
6
  CONTROL_SEC = 'control_sec'
7
7
  OCCUPANCY_CHANNEL_PREFIX = '[?occupancy=metrics.publishers]'
8
8
  FETCH_BACK_OFF_BASE_RETRIES = 1
9
+ PUSH_CONNECTED = 'PUSH_CONNECTED'
10
+ PUSH_RETRYABLE_ERROR = 'PUSH_RETRYABLE_ERROR'
11
+ PUSH_NONRETRYABLE_ERROR = 'PUSH_NONRETRYABLE_ERROR'
12
+ PUSH_SUBSYSTEM_DOWN = 'PUSH_SUBSYSTEM_DOWN'
13
+ PUSH_SUBSYSTEM_READY = 'PUSH_SUBSYSTEM_READY'
14
+ PUSH_SUBSYSTEM_OFF = 'PUSH_SUBSYSTEM_OFF'
9
15
  end
10
-
@@ -8,12 +8,13 @@ module SplitIoClient
8
8
  RUBY_ENCODING = '1.9'.respond_to?(:force_encoding)
9
9
 
10
10
  def initialize(config)
11
- @config = config
11
+ @config = config
12
12
  end
13
13
 
14
- def get_api(url, api_key, params = {})
14
+ def get_api(url, api_key, params = {}, cache_control_headers = false)
15
15
  api_client.get(url, params) do |req|
16
16
  req.headers = common_headers(api_key).merge('Accept-Encoding' => 'gzip')
17
+ req.headers = req.headers.merge('Cache-Control' => 'no-cache') if cache_control_headers
17
18
 
18
19
  req.options[:timeout] = @config.read_timeout
19
20
  req.options[:open_timeout] = @config.connection_timeout
@@ -3,9 +3,10 @@
3
3
  module SplitIoClient
4
4
  module Api
5
5
  class Events < Client
6
- def initialize(api_key, config)
6
+ def initialize(api_key, config, telemetry_runtime_producer)
7
7
  super(config)
8
8
  @api_key = api_key
9
+ @telemetry_runtime_producer = telemetry_runtime_producer
9
10
  end
10
11
 
11
12
  def post(events)
@@ -14,6 +15,8 @@ module SplitIoClient
14
15
  return
15
16
  end
16
17
 
18
+ start = Time.now
19
+
17
20
  events.each_slice(@config.events_queue_size) do |events_slice|
18
21
  response = post_api(
19
22
  "#{@config.events_uri}/events/bulk",
@@ -23,7 +26,13 @@ module SplitIoClient
23
26
 
24
27
  if response.success?
25
28
  @config.split_logger.log_if_debug("Events reported: #{events_slice.size}")
29
+
30
+ bucket = BinarySearchLatencyTracker.get_bucket((Time.now - start) * 1000.0)
31
+ @telemetry_runtime_producer.record_sync_latency(Telemetry::Domain::Constants::EVENT_SYNC, bucket)
32
+ @telemetry_runtime_producer.record_successful_sync(Telemetry::Domain::Constants::EVENT_SYNC, (Time.now.to_f * 1000.0).to_i)
26
33
  else
34
+ @telemetry_runtime_producer.record_sync_error(Telemetry::Domain::Constants::EVENT_SYNC, response.status)
35
+
27
36
  @config.logger.error("Unexpected status code while posting events: #{response.status}." \
28
37
  ' - Check your API key and base URI')
29
38
  raise 'Split SDK failed to connect to backend to post events'
@@ -3,9 +3,10 @@
3
3
  module SplitIoClient
4
4
  module Api
5
5
  class Impressions < Client
6
- def initialize(api_key, config)
6
+ def initialize(api_key, config, telemetry_runtime_producer)
7
+ super(config)
7
8
  @api_key = api_key
8
- @config = config
9
+ @telemetry_runtime_producer = telemetry_runtime_producer
9
10
  end
10
11
 
11
12
  def post(impressions)
@@ -14,11 +15,19 @@ module SplitIoClient
14
15
  return
15
16
  end
16
17
 
18
+ start = Time.now
19
+
17
20
  response = post_api("#{@config.events_uri}/testImpressions/bulk", @api_key, impressions, impressions_headers)
18
21
 
19
22
  if response.success?
20
23
  @config.split_logger.log_if_debug("Impressions reported: #{total_impressions(impressions)}")
24
+
25
+ bucket = BinarySearchLatencyTracker.get_bucket((Time.now - start) * 1000.0)
26
+ @telemetry_runtime_producer.record_sync_latency(Telemetry::Domain::Constants::IMPRESSIONS_SYNC, bucket)
27
+ @telemetry_runtime_producer.record_successful_sync(Telemetry::Domain::Constants::IMPRESSIONS_SYNC, (Time.now.to_f * 1000.0).to_i)
21
28
  else
29
+ @telemetry_runtime_producer.record_sync_error(Telemetry::Domain::Constants::IMPRESSIONS_SYNC, response.status)
30
+
22
31
  @config.logger.error("Unexpected status code while posting impressions: #{response.status}." \
23
32
  ' - Check your API key and base URI')
24
33
  raise 'Split SDK failed to connect to backend to post impressions'
@@ -31,11 +40,19 @@ module SplitIoClient
31
40
  return
32
41
  end
33
42
 
43
+ start = Time.now
44
+
34
45
  response = post_api("#{@config.events_uri}/testImpressions/count", @api_key, impressions_count)
35
46
 
36
47
  if response.success?
37
48
  @config.split_logger.log_if_debug("Impressions count sent: #{impressions_count[:pf].length}")
49
+
50
+ bucket = BinarySearchLatencyTracker.get_bucket((Time.now - start) * 1000.0)
51
+ @telemetry_runtime_producer.record_sync_latency(Telemetry::Domain::Constants::IMPRESSION_COUNT_SYNC, bucket)
52
+ @telemetry_runtime_producer.record_successful_sync(Telemetry::Domain::Constants::IMPRESSION_COUNT_SYNC, (Time.now.to_f * 1000.0).to_i)
38
53
  else
54
+ @telemetry_runtime_producer.record_sync_error(Telemetry::Domain::Constants::IMPRESSION_COUNT_SYNC, response.status)
55
+
39
56
  @config.logger.error("Unexpected status code while posting impressions count: #{response.status}." \
40
57
  ' - Check your API key and base URI')
41
58
  raise 'Split SDK failed to connect to backend to post impressions'
@@ -4,24 +4,20 @@ module SplitIoClient
4
4
  module Api
5
5
  # Retrieves segment changes from the Split Backend
6
6
  class Segments < Client
7
- METRICS_PREFIX = 'segmentChangeFetcher'
8
-
9
- def initialize(api_key, metrics, segments_repository, config)
7
+ def initialize(api_key, segments_repository, config, telemetry_runtime_producer)
10
8
  super(config)
11
- @metrics = metrics
12
9
  @api_key = api_key
13
10
  @segments_repository = segments_repository
11
+ @telemetry_runtime_producer = telemetry_runtime_producer
14
12
  end
15
13
 
16
- def fetch_segments_by_names(names)
17
- start = Time.now
18
-
14
+ def fetch_segments_by_names(names, cache_control_headers = false)
19
15
  return if names.nil? || names.empty?
20
16
 
21
17
  names.each do |name|
22
18
  since = @segments_repository.get_change_number(name)
23
19
  loop do
24
- segment = fetch_segment_changes(name, since)
20
+ segment = fetch_segment_changes(name, since, cache_control_headers)
25
21
  @segments_repository.add_to_segment(segment)
26
22
 
27
23
  @config.split_logger.log_if_debug("Segment #{name} fetched before: #{since}, \
@@ -32,19 +28,17 @@ module SplitIoClient
32
28
  since = @segments_repository.get_change_number(name)
33
29
  end
34
30
  end
35
-
36
- latency = (Time.now - start) * 1000.0
37
- @metrics.time(METRICS_PREFIX + '.time', latency)
38
31
  end
39
32
 
40
33
  private
41
34
 
42
- def fetch_segment_changes(name, since)
43
- response = get_api("#{@config.base_uri}/segmentChanges/#{name}", @api_key, since: since)
35
+ def fetch_segment_changes(name, since, cache_control_headers = false)
36
+ start = Time.now
37
+ response = get_api("#{@config.base_uri}/segmentChanges/#{name}", @api_key, { since: since }, cache_control_headers)
38
+
44
39
  if response.success?
45
40
  segment = JSON.parse(response.body, symbolize_names: true)
46
41
  @segments_repository.set_change_number(name, segment[:till])
47
- @metrics.count(METRICS_PREFIX + '.status.' + response.status.to_s, 1)
48
42
 
49
43
  @config.split_logger.log_if_debug("\'#{segment[:name]}\' segment retrieved.")
50
44
  unless segment[:added].empty?
@@ -55,15 +49,23 @@ module SplitIoClient
55
49
  end
56
50
  @config.split_logger.log_if_transport("Segment changes response: #{segment.to_s}")
57
51
 
52
+ bucket = BinarySearchLatencyTracker.get_bucket((Time.now - start) * 1000.0)
53
+ @telemetry_runtime_producer.record_sync_latency(Telemetry::Domain::Constants::SEGMENT_SYNC, bucket)
54
+ @telemetry_runtime_producer.record_successful_sync(Telemetry::Domain::Constants::SEGMENT_SYNC, (Time.now.to_f * 1000.0).to_i)
55
+
58
56
  segment
59
57
  elsif response.status == 403
60
- @config.logger.error('Factory Instantiation: You passed a browser type api_key, ' \
61
- 'please grab an api key from the Split console that is of type sdk')
62
- @config.valid_mode = false
58
+ @telemetry_runtime_producer.record_sync_error(Telemetry::Domain::Constants::SEGMENT_SYNC, response.status)
59
+
60
+ @config.logger.error('Factory Instantiation: You passed a browser type api_key, ' \
61
+ 'please grab an api key from the Split console that is of type sdk')
62
+ @config.valid_mode = false
63
63
  else
64
+ @telemetry_runtime_producer.record_sync_error(Telemetry::Domain::Constants::SEGMENT_SYNC, response.status)
65
+
64
66
  @config.logger.error("Unexpected status code while fetching segments: #{response.status}." \
65
67
  "Since #{since} - Check your API key and base URI")
66
- @metrics.count(METRICS_PREFIX + '.status.' + response.status.to_s, 1)
68
+
67
69
  raise 'Split SDK failed to connect to backend to fetch segments'
68
70
  end
69
71
  end
@@ -4,35 +4,35 @@ module SplitIoClient
4
4
  module Api
5
5
  # Retrieves split definitions from the Split Backend
6
6
  class Splits < Client
7
- METRICS_PREFIX = 'splitChangeFetcher'
8
-
9
- def initialize(api_key, metrics, config)
7
+ def initialize(api_key, config, telemetry_runtime_producer)
10
8
  super(config)
11
9
  @api_key = api_key
12
- @metrics = metrics
10
+ @telemetry_runtime_producer = telemetry_runtime_producer
13
11
  end
14
12
 
15
- def since(since)
13
+ def since(since, cache_control_headers = false)
16
14
  start = Time.now
17
15
 
18
- response = get_api("#{@config.base_uri}/splitChanges", @api_key, since: since)
16
+ response = get_api("#{@config.base_uri}/splitChanges", @api_key, { since: since }, cache_control_headers)
19
17
  if response.success?
20
18
  result = splits_with_segment_names(response.body)
21
19
 
22
- @metrics.count(METRICS_PREFIX + '.status.' + response.status.to_s, 1)
23
20
  unless result[:splits].empty?
24
21
  @config.split_logger.log_if_debug("#{result[:splits].length} splits retrieved. since=#{since}")
25
22
  end
26
23
  @config.split_logger.log_if_transport("Split changes response: #{result.to_s}")
27
24
 
28
- latency = (Time.now - start) * 1000.0
29
- @metrics.time(METRICS_PREFIX + '.time', latency)
25
+ bucket = BinarySearchLatencyTracker.get_bucket((Time.now - start) * 1000.0)
26
+ @telemetry_runtime_producer.record_sync_latency(Telemetry::Domain::Constants::SPLIT_SYNC, bucket)
27
+ @telemetry_runtime_producer.record_successful_sync(Telemetry::Domain::Constants::SPLIT_SYNC, (Time.now.to_f * 1000.0).to_i)
30
28
 
31
29
  result
32
30
  else
33
- @metrics.count(METRICS_PREFIX + '.status.' + response.status.to_s, 1)
31
+ @telemetry_runtime_producer.record_sync_error(Telemetry::Domain::Constants::SPLIT_SYNC, response.status)
32
+
34
33
  @config.logger.error("Unexpected status code while fetching splits: #{response.status}. " \
35
34
  'Check your API key and base URI')
35
+
36
36
  raise 'Split SDK failed to connect to backend to fetch split definitions'
37
37
  end
38
38
  end
@@ -0,0 +1,39 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SplitIoClient
4
+ module Api
5
+ class TelemetryApi < Client
6
+ def initialize(config, api_key, telemetry_runtime_producer)
7
+ super(config)
8
+ @api_key = api_key
9
+ @telemetry_runtime_producer = telemetry_runtime_producer
10
+ end
11
+
12
+ def record_init(config_init)
13
+ post_telemetry("#{@config.telemetry_service_url}/metrics/config", config_init, 'init')
14
+ end
15
+
16
+ def record_stats(stats)
17
+ post_telemetry("#{@config.telemetry_service_url}/metrics/usage", stats, 'stats')
18
+ end
19
+
20
+ private
21
+
22
+ def post_telemetry(url, obj, method)
23
+ start = Time.now
24
+ response = post_api(url, @api_key, obj)
25
+
26
+ if response.success?
27
+ @config.split_logger.log_if_debug("Telemetry post succeeded: record #{method}.")
28
+
29
+ bucket = BinarySearchLatencyTracker.get_bucket((Time.now - start) * 1000.0)
30
+ @telemetry_runtime_producer.record_sync_latency(Telemetry::Domain::Constants::TELEMETRY_SYNC, bucket)
31
+ @telemetry_runtime_producer.record_successful_sync(Telemetry::Domain::Constants::TELEMETRY_SYNC, (Time.now.to_f * 1000.0).to_i)
32
+ else
33
+ @telemetry_runtime_producer.record_sync_error(Telemetry::Domain::Constants::TELEMETRY_SYNC, response.status)
34
+ @config.logger.error("Unexpected status code while posting telemetry #{method}: #{response.status}.")
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end