splitclient-rb 7.2.3 → 7.3.0.pre.rc1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (64) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +12 -0
  3. data/lib/splitclient-rb.rb +24 -9
  4. data/lib/splitclient-rb/cache/adapters/redis_adapter.rb +4 -0
  5. data/lib/splitclient-rb/cache/fetchers/segment_fetcher.rb +8 -7
  6. data/lib/splitclient-rb/cache/fetchers/split_fetcher.rb +7 -7
  7. data/lib/splitclient-rb/cache/repositories/events/memory_repository.rb +6 -3
  8. data/lib/splitclient-rb/cache/repositories/events_repository.rb +4 -3
  9. data/lib/splitclient-rb/cache/repositories/impressions/memory_repository.rb +8 -0
  10. data/lib/splitclient-rb/cache/repositories/impressions/redis_repository.rb +2 -0
  11. data/lib/splitclient-rb/cache/repositories/repository.rb +0 -4
  12. data/lib/splitclient-rb/cache/repositories/segments_repository.rb +20 -0
  13. data/lib/splitclient-rb/cache/repositories/splits_repository.rb +4 -0
  14. data/lib/splitclient-rb/cache/senders/localhost_repo_cleaner.rb +1 -3
  15. data/lib/splitclient-rb/cache/stores/sdk_blocker.rb +9 -0
  16. data/lib/splitclient-rb/clients/split_client.rb +59 -25
  17. data/lib/splitclient-rb/engine/api/client.rb +3 -2
  18. data/lib/splitclient-rb/engine/api/events.rb +10 -1
  19. data/lib/splitclient-rb/engine/api/impressions.rb +19 -2
  20. data/lib/splitclient-rb/engine/api/segments.rb +20 -18
  21. data/lib/splitclient-rb/engine/api/splits.rb +10 -10
  22. data/lib/splitclient-rb/engine/api/telemetry_api.rb +39 -0
  23. data/lib/splitclient-rb/engine/auth_api_client.rb +21 -8
  24. data/lib/splitclient-rb/engine/common/impressions_manager.rb +27 -3
  25. data/lib/splitclient-rb/engine/metrics/binary_search_latency_tracker.rb +3 -65
  26. data/lib/splitclient-rb/engine/push_manager.rb +10 -2
  27. data/lib/splitclient-rb/engine/sync_manager.rb +42 -20
  28. data/lib/splitclient-rb/engine/synchronizer.rb +13 -12
  29. data/lib/splitclient-rb/split_config.rb +46 -21
  30. data/lib/splitclient-rb/split_factory.rb +31 -13
  31. data/lib/splitclient-rb/split_factory_registry.rb +12 -0
  32. data/lib/splitclient-rb/sse/event_source/client.rb +10 -1
  33. data/lib/splitclient-rb/sse/notification_manager_keeper.rb +17 -3
  34. data/lib/splitclient-rb/sse/sse_handler.rb +10 -6
  35. data/lib/splitclient-rb/telemetry/domain/constants.rb +42 -0
  36. data/lib/splitclient-rb/telemetry/domain/structs.rb +31 -0
  37. data/lib/splitclient-rb/telemetry/evaluation_consumer.rb +14 -0
  38. data/lib/splitclient-rb/telemetry/evaluation_producer.rb +21 -0
  39. data/lib/splitclient-rb/telemetry/init_consumer.rb +14 -0
  40. data/lib/splitclient-rb/telemetry/init_producer.rb +19 -0
  41. data/lib/splitclient-rb/telemetry/memory/memory_evaluation_consumer.rb +32 -0
  42. data/lib/splitclient-rb/telemetry/memory/memory_evaluation_producer.rb +24 -0
  43. data/lib/splitclient-rb/telemetry/memory/memory_init_consumer.rb +28 -0
  44. data/lib/splitclient-rb/telemetry/memory/memory_init_producer.rb +34 -0
  45. data/lib/splitclient-rb/telemetry/memory/memory_runtime_consumer.rb +112 -0
  46. data/lib/splitclient-rb/telemetry/memory/memory_runtime_producer.rb +81 -0
  47. data/lib/splitclient-rb/telemetry/memory/memory_synchronizer.rb +192 -0
  48. data/lib/splitclient-rb/telemetry/redis/redis_evaluation_producer.rb +38 -0
  49. data/lib/splitclient-rb/telemetry/redis/redis_init_producer.rb +37 -0
  50. data/lib/splitclient-rb/telemetry/redis/redis_synchronizer.rb +28 -0
  51. data/lib/splitclient-rb/telemetry/runtime_consumer.rb +24 -0
  52. data/lib/splitclient-rb/telemetry/runtime_producer.rb +24 -0
  53. data/lib/splitclient-rb/telemetry/storages/memory.rb +139 -0
  54. data/lib/splitclient-rb/telemetry/sync_task.rb +38 -0
  55. data/lib/splitclient-rb/telemetry/synchronizer.rb +29 -0
  56. data/lib/splitclient-rb/version.rb +1 -1
  57. metadata +26 -11
  58. data/lib/splitclient-rb/cache/repositories/metrics/memory_repository.rb +0 -163
  59. data/lib/splitclient-rb/cache/repositories/metrics/redis_repository.rb +0 -131
  60. data/lib/splitclient-rb/cache/repositories/metrics_repository.rb +0 -23
  61. data/lib/splitclient-rb/cache/senders/metrics_sender.rb +0 -55
  62. data/lib/splitclient-rb/engine/api/metrics.rb +0 -61
  63. data/lib/splitclient-rb/engine/metrics/metrics.rb +0 -80
  64. data/lib/splitclient-rb/redis_metrics_fixer.rb +0 -36
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 667aa0e132a8afc583c430b1370d9a0aa0aca51ece3a97b32b376569198e91c7
4
- data.tar.gz: b85a8b28d862c08a9d079a74aac01ffc849c6ffe1662e5d7fbe12b665e05119e
3
+ metadata.gz: a4470d045e5590e6b67c6342dfb3be96e8364de55f2f3d4358e843f3b0563116
4
+ data.tar.gz: b03c398497670ef911e080fa61797092bad75c1a760c8511794096497ce80df0
5
5
  SHA512:
6
- metadata.gz: 04f02ce8f4359cedcfec7517cf1132b8b3b3edb7059f385e10a4be4c83984465e6faa044ce6a80d743531986a60b76d658f48325c0eddada28724a5f7c99d5c9
7
- data.tar.gz: 83519c96a2e15e268cb1756e42b9e0b2385b52bcd6e7bc364e1d36f8c3bb667d0f17e2f83288f43528deec7a15435744c903b3209c43e4204c5f20c307263cce
6
+ metadata.gz: a37d9bd3d1ece1092f548a9e87ba47ac97b4af881bca52ff5fe8acca50071e053bdfd1ccb7b36e62dfb5351f677bcb5e60b72af63af1b84d7c6b188c1bcbf66d
7
+ data.tar.gz: 2f1e0369cc0e0a96c28628e6fa79f174e22b31ab7e447282a2132554a61d15d7653edd75b5e9b8c31b9c4d8af77af163d0d5ebb9ed2f0a364f5c15137945c3dd
data/.rubocop.yml CHANGED
@@ -3,16 +3,26 @@ Documentation:
3
3
 
4
4
  Metrics/AbcSize:
5
5
  Max: 26
6
+ Exclude:
7
+ - lib/splitclient-rb/telemetry/memory/memory_synchronizer.rb
6
8
 
7
9
  Metrics/MethodLength:
8
10
  Max: 20
11
+ Exclude:
12
+ - lib/splitclient-rb/telemetry/memory/memory_synchronizer.rb
9
13
 
10
14
  Metrics/ClassLength:
11
15
  Max: 150
16
+ Exclude:
17
+ - lib/splitclient-rb/telemetry/memory/memory_synchronizer.rb
12
18
 
13
19
  Metrics/CyclomaticComplexity:
14
20
  Max: 8
15
21
 
22
+ Metrics/ParameterLists:
23
+ Exclude:
24
+ - lib/splitclient-rb/engine/sync_manager.rb
25
+
16
26
  Metrics/LineLength:
17
27
  Max: 130
18
28
  Exclude:
@@ -20,6 +30,7 @@ Metrics/LineLength:
20
30
  - spec/integrations/**/*
21
31
  - spec/engine/sync_manager_spec.rb
22
32
  - spec/engine/auth_api_client_spec.rb
33
+ - spec/telemetry/synchronizer_spec.rb
23
34
 
24
35
  Style/BracesAroundHashParameters:
25
36
  Exclude:
@@ -50,3 +61,4 @@ AllCops:
50
61
  - lib/splitclient-rb/engine/metrics/**/*
51
62
  - lib/splitclient-rb/engine/models/**/*
52
63
  - lib/splitclient-rb/engine/parser/**/*
64
+ - spec/telemetry/synchronizer_spec.rb
@@ -23,12 +23,8 @@ require 'splitclient-rb/cache/repositories/events/memory_repository'
23
23
  require 'splitclient-rb/cache/repositories/events/redis_repository'
24
24
  require 'splitclient-rb/cache/repositories/impressions/memory_repository'
25
25
  require 'splitclient-rb/cache/repositories/impressions/redis_repository'
26
- require 'splitclient-rb/cache/repositories/metrics_repository'
27
- require 'splitclient-rb/cache/repositories/metrics/memory_repository'
28
- require 'splitclient-rb/cache/repositories/metrics/redis_repository'
29
26
  require 'splitclient-rb/cache/senders/impressions_formatter'
30
27
  require 'splitclient-rb/cache/senders/impressions_sender'
31
- require 'splitclient-rb/cache/senders/metrics_sender'
32
28
  require 'splitclient-rb/cache/senders/events_sender'
33
29
  require 'splitclient-rb/cache/senders/impressions_count_sender'
34
30
  require 'splitclient-rb/cache/senders/localhost_repo_cleaner'
@@ -51,10 +47,10 @@ require 'splitclient-rb/engine/api/faraday_middleware/gzip'
51
47
  require 'splitclient-rb/engine/api/faraday_adapter/patched_net_http_persistent'
52
48
  require 'splitclient-rb/engine/api/client'
53
49
  require 'splitclient-rb/engine/api/impressions'
54
- require 'splitclient-rb/engine/api/metrics'
55
50
  require 'splitclient-rb/engine/api/segments'
56
51
  require 'splitclient-rb/engine/api/splits'
57
52
  require 'splitclient-rb/engine/api/events'
53
+ require 'splitclient-rb/engine/api/telemetry_api'
58
54
  require 'splitclient-rb/engine/common/impressions_counter'
59
55
  require 'splitclient-rb/engine/common/impressions_manager'
60
56
  require 'splitclient-rb/engine/parser/condition'
@@ -84,7 +80,6 @@ require 'splitclient-rb/engine/matchers/equal_to_boolean_matcher'
84
80
  require 'splitclient-rb/engine/matchers/equal_to_matcher'
85
81
  require 'splitclient-rb/engine/matchers/matches_string_matcher'
86
82
  require 'splitclient-rb/engine/evaluator/splitter'
87
- require 'splitclient-rb/engine/metrics/metrics'
88
83
  require 'splitclient-rb/engine/metrics/binary_search_latency_tracker'
89
84
  require 'splitclient-rb/engine/models/split'
90
85
  require 'splitclient-rb/engine/models/label'
@@ -95,9 +90,6 @@ require 'splitclient-rb/engine/sync_manager'
95
90
  require 'splitclient-rb/engine/synchronizer'
96
91
  require 'splitclient-rb/utilitites'
97
92
 
98
- # redis metrics fixer
99
- require 'splitclient-rb/redis_metrics_fixer'
100
-
101
93
  # SSE
102
94
  require 'splitclient-rb/sse/event_source/back_off'
103
95
  require 'splitclient-rb/sse/event_source/client'
@@ -110,6 +102,29 @@ require 'splitclient-rb/sse/notification_manager_keeper'
110
102
  require 'splitclient-rb/sse/notification_processor'
111
103
  require 'splitclient-rb/sse/sse_handler'
112
104
 
105
+ # Telemetry
106
+ require 'splitclient-rb/telemetry/domain/constants'
107
+ require 'splitclient-rb/telemetry/domain/structs'
108
+ require 'splitclient-rb/telemetry/storages/memory'
109
+ require 'splitclient-rb/telemetry/evaluation_consumer'
110
+ require 'splitclient-rb/telemetry/evaluation_producer'
111
+ require 'splitclient-rb/telemetry/init_consumer'
112
+ require 'splitclient-rb/telemetry/init_producer'
113
+ require 'splitclient-rb/telemetry/runtime_consumer'
114
+ require 'splitclient-rb/telemetry/runtime_producer'
115
+ require 'splitclient-rb/telemetry/sync_task'
116
+ require 'splitclient-rb/telemetry/synchronizer'
117
+ require 'splitclient-rb/telemetry/memory/memory_evaluation_consumer'
118
+ require 'splitclient-rb/telemetry/memory/memory_evaluation_producer'
119
+ require 'splitclient-rb/telemetry/memory/memory_init_consumer'
120
+ require 'splitclient-rb/telemetry/memory/memory_init_producer'
121
+ require 'splitclient-rb/telemetry/memory/memory_runtime_consumer'
122
+ require 'splitclient-rb/telemetry/memory/memory_runtime_producer'
123
+ require 'splitclient-rb/telemetry/memory/memory_synchronizer'
124
+ require 'splitclient-rb/telemetry/redis/redis_evaluation_producer'
125
+ require 'splitclient-rb/telemetry/redis/redis_init_producer'
126
+ require 'splitclient-rb/telemetry/redis/redis_synchronizer'
127
+
113
128
  # C extension
114
129
  require 'murmurhash/murmurhash_mri'
115
130
 
@@ -17,6 +17,10 @@ module SplitIoClient
17
17
  @redis = Redis.new(connection)
18
18
  end
19
19
 
20
+ def hincrby(key, field, increment)
21
+ @redis.hincrby(key, field, increment)
22
+ end
23
+
20
24
  # Map
21
25
  def initialize_map(key)
22
26
  # No need to initialize hash/map in Redis
@@ -4,13 +4,13 @@ module SplitIoClient
4
4
  class SegmentFetcher
5
5
  attr_reader :segments_repository
6
6
 
7
- def initialize(segments_repository, api_key, metrics, config, sdk_blocker = nil)
7
+ def initialize(segments_repository, api_key, config, sdk_blocker, telemetry_runtime_producer)
8
8
  @segments_repository = segments_repository
9
9
  @api_key = api_key
10
- @metrics = metrics
11
10
  @config = config
12
11
  @sdk_blocker = sdk_blocker
13
12
  @semaphore = Mutex.new
13
+ @telemetry_runtime_producer = telemetry_runtime_producer
14
14
  end
15
15
 
16
16
  def call
@@ -27,19 +27,19 @@ module SplitIoClient
27
27
  end
28
28
  end
29
29
 
30
- def fetch_segments_if_not_exists(names)
30
+ def fetch_segments_if_not_exists(names, cache_control_headers = false)
31
31
  names.each do |name|
32
32
  change_number = @segments_repository.get_change_number(name)
33
33
 
34
- fetch_segment(name) if change_number == -1
34
+ fetch_segment(name, cache_control_headers) if change_number == -1
35
35
  end
36
36
  rescue StandardError => error
37
37
  @config.log_found_exception(__method__.to_s, error)
38
38
  end
39
39
 
40
- def fetch_segment(name)
40
+ def fetch_segment(name, cache_control_headers = false)
41
41
  @semaphore.synchronize do
42
- segments_api.fetch_segments_by_names([name])
42
+ segments_api.fetch_segments_by_names([name], cache_control_headers)
43
43
  end
44
44
  rescue StandardError => error
45
45
  @config.log_found_exception(__method__.to_s, error)
@@ -50,6 +50,7 @@ module SplitIoClient
50
50
  segments_api.fetch_segments_by_names(@segments_repository.used_segment_names)
51
51
 
52
52
  @sdk_blocker.segments_ready!
53
+ @sdk_blocker.sdk_internal_ready
53
54
  end
54
55
  rescue StandardError => error
55
56
  @config.log_found_exception(__method__.to_s, error)
@@ -79,7 +80,7 @@ module SplitIoClient
79
80
  end
80
81
 
81
82
  def segments_api
82
- @segments_api ||= SplitIoClient::Api::Segments.new(@api_key, @metrics, @segments_repository, @config)
83
+ @segments_api ||= SplitIoClient::Api::Segments.new(@api_key, @segments_repository, @config, @telemetry_runtime_producer)
83
84
  end
84
85
  end
85
86
  end
@@ -4,13 +4,13 @@ module SplitIoClient
4
4
  class SplitFetcher
5
5
  attr_reader :splits_repository
6
6
 
7
- def initialize(splits_repository, api_key, metrics, config, sdk_blocker = nil)
7
+ def initialize(splits_repository, api_key, config, sdk_blocker, telemetry_runtime_producer)
8
8
  @splits_repository = splits_repository
9
9
  @api_key = api_key
10
- @metrics = metrics
11
10
  @config = config
12
11
  @sdk_blocker = sdk_blocker
13
12
  @semaphore = Mutex.new
13
+ @telemetry_runtime_producer = telemetry_runtime_producer
14
14
  end
15
15
 
16
16
  def call
@@ -27,9 +27,9 @@ module SplitIoClient
27
27
  end
28
28
  end
29
29
 
30
- def fetch_splits
30
+ def fetch_splits(cache_control_headers = false)
31
31
  @semaphore.synchronize do
32
- data = splits_since(@splits_repository.get_change_number)
32
+ data = splits_since(@splits_repository.get_change_number, cache_control_headers)
33
33
 
34
34
  data[:splits] && data[:splits].each do |split|
35
35
  add_split_unless_archived(split)
@@ -67,8 +67,8 @@ module SplitIoClient
67
67
  end
68
68
  end
69
69
 
70
- def splits_since(since)
71
- splits_api.since(since)
70
+ def splits_since(since, cache_control_headers = false)
71
+ splits_api.since(since, cache_control_headers)
72
72
  end
73
73
 
74
74
  def add_split_unless_archived(split)
@@ -94,7 +94,7 @@ module SplitIoClient
94
94
  end
95
95
 
96
96
  def splits_api
97
- @splits_api ||= SplitIoClient::Api::Splits.new(@api_key, @metrics, @config)
97
+ @splits_api ||= SplitIoClient::Api::Splits.new(@api_key, @config, @telemetry_runtime_producer)
98
98
  end
99
99
  end
100
100
  end
@@ -5,10 +5,11 @@ module SplitIoClient
5
5
  class MemoryRepository < EventsRepository
6
6
  EVENTS_MAX_SIZE_BYTES = 5242880
7
7
 
8
- def initialize(config)
8
+ def initialize(config, telemetry_runtime_producer)
9
9
  @config = config
10
10
  @adapter = @config.events_adapter
11
11
  @size = 0
12
+ @telemetry_runtime_producer = telemetry_runtime_producer
12
13
  end
13
14
 
14
15
  def add(key, traffic_type, event_type, time, value, properties, event_size)
@@ -17,8 +18,10 @@ module SplitIoClient
17
18
 
18
19
  post_events if @size >= EVENTS_MAX_SIZE_BYTES || @adapter.length == @config.events_queue_size
19
20
 
20
- rescue StandardError => error
21
- @config.log_found_exception(__method__.to_s, error)
21
+ @telemetry_runtime_producer.record_events_stats(Telemetry::Domain::Constants::EVENTS_QUEUED, 1)
22
+ rescue StandardError => error
23
+ @config.log_found_exception(__method__.to_s, error)
24
+ @telemetry_runtime_producer.record_events_stats(Telemetry::Domain::Constants::EVENTS_DROPPED, 1)
22
25
  end
23
26
 
24
27
  def clear
@@ -6,16 +6,17 @@ module SplitIoClient
6
6
  extend Forwardable
7
7
  def_delegators :@repository, :add, :clear, :batch
8
8
 
9
- def initialize(config, api_key)
9
+ def initialize(config, api_key, telemetry_runtime_producer)
10
10
  super(config)
11
11
  @repository = case @config.events_adapter.class.to_s
12
12
  when 'SplitIoClient::Cache::Adapters::MemoryAdapter'
13
- Repositories::Events::MemoryRepository.new(@config)
13
+ Repositories::Events::MemoryRepository.new(@config, telemetry_runtime_producer)
14
14
  when 'SplitIoClient::Cache::Adapters::RedisAdapter'
15
15
  Repositories::Events::RedisRepository.new(@config)
16
16
  end
17
17
 
18
18
  @api_key = api_key
19
+ @telemetry_runtime_producer = telemetry_runtime_producer
19
20
  end
20
21
 
21
22
  def post_events
@@ -48,7 +49,7 @@ module SplitIoClient
48
49
  private
49
50
 
50
51
  def events_api
51
- @events_api ||= SplitIoClient::Api::Events.new(@api_key, @config)
52
+ @events_api ||= SplitIoClient::Api::Events.new(@api_key, @config, @telemetry_runtime_producer)
52
53
  end
53
54
  end
54
55
  end
@@ -11,15 +11,23 @@ module SplitIoClient
11
11
  end
12
12
 
13
13
  def add_bulk(impressions)
14
+ return 0 if impressions.nil?
15
+
16
+ count = 0
14
17
  impressions.each do |impression|
15
18
  @adapter.add_to_queue(impression)
19
+ count += 1
16
20
  end
21
+
22
+ 0
17
23
  rescue ThreadError # queue is full
18
24
  if random_sampler.rand(1..1000) <= 2 # log only 0.2 % of the time
19
25
  @config.logger.warn("Dropping impressions. Current size is \
20
26
  #{@config.impressions_queue_size}. " \
21
27
  'Consider increasing impressions_queue_size')
22
28
  end
29
+
30
+ impressions.length - count
23
31
  end
24
32
 
25
33
  def batch
@@ -21,8 +21,10 @@ module SplitIoClient
21
21
 
22
22
  # Synchronizer might not be running
23
23
  @adapter.expire(key, EXPIRE_SECONDS) if impressions_json.size == impressions_list_size
24
+ 0
24
25
  rescue StandardError => e
25
26
  @config.logger.error("Exception while add_bulk: #{e}")
27
+ 0
26
28
  end
27
29
 
28
30
  def get_impressions(number_of_impressions = 0)
@@ -19,10 +19,6 @@ module SplitIoClient
19
19
  def namespace_key(key = '')
20
20
  "#{@config.redis_namespace}#{key}"
21
21
  end
22
-
23
- def impressions_metrics_key(key)
24
- namespace_key("/#{@config.language}-#{@config.version}/#{@config.machine_ip}/#{key}")
25
- end
26
22
  end
27
23
  end
28
24
  end
@@ -63,6 +63,26 @@ module SplitIoClient
63
63
  @adapter.clear(namespace_key)
64
64
  end
65
65
 
66
+ def segments_count
67
+ used_segment_names.length
68
+ end
69
+
70
+ def segment_keys_count
71
+ names = used_segment_names
72
+
73
+ keys = 0
74
+
75
+ names.each do |name|
76
+ segment_keys = get_segment_keys(name)
77
+ keys += segment_keys.length
78
+ end
79
+
80
+ keys
81
+ rescue StandardError => error
82
+ @config.log_found_exception(__method__.to_s, error)
83
+ 0
84
+ end
85
+
66
86
  private
67
87
 
68
88
  def segment_data(name)
@@ -140,6 +140,10 @@ module SplitIoClient
140
140
  @adapter.set_string(namespace_key(".split.#{split_name}"), split.to_json)
141
141
  end
142
142
 
143
+ def splits_count
144
+ split_names.length
145
+ end
146
+
143
147
  private
144
148
 
145
149
  def increase_tt_name_count(tt_name)
@@ -4,9 +4,8 @@ module SplitIoClient
4
4
  module Cache
5
5
  module Senders
6
6
  class LocalhostRepoCleaner
7
- def initialize(impressions_repository, metrics_repository, events_repository, config)
7
+ def initialize(impressions_repository, events_repository, config)
8
8
  @impressions_repository = impressions_repository
9
- @metrics_repository = metrics_repository
10
9
  @events_repository = events_repository
11
10
  @config = config
12
11
  end
@@ -40,7 +39,6 @@ module SplitIoClient
40
39
 
41
40
  def clear_repositories
42
41
  @impressions_repository.clear
43
- @metrics_repository.clear
44
42
  @events_repository.clear
45
43
  end
46
44
  end
@@ -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