splitclient-rb 7.2.3.pre.rc1 → 7.3.0.pre.rc3
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.
- checksums.yaml +4 -4
- data/.rubocop.yml +12 -0
- data/CHANGES.txt +6 -0
- data/lib/splitclient-rb.rb +24 -9
- data/lib/splitclient-rb/cache/adapters/redis_adapter.rb +4 -0
- data/lib/splitclient-rb/cache/fetchers/segment_fetcher.rb +21 -9
- data/lib/splitclient-rb/cache/fetchers/split_fetcher.rb +10 -9
- data/lib/splitclient-rb/cache/repositories/events/memory_repository.rb +6 -3
- data/lib/splitclient-rb/cache/repositories/events_repository.rb +4 -3
- data/lib/splitclient-rb/cache/repositories/impressions/memory_repository.rb +8 -0
- data/lib/splitclient-rb/cache/repositories/impressions/redis_repository.rb +2 -0
- data/lib/splitclient-rb/cache/repositories/repository.rb +0 -4
- data/lib/splitclient-rb/cache/repositories/segments_repository.rb +20 -0
- data/lib/splitclient-rb/cache/repositories/splits_repository.rb +4 -0
- data/lib/splitclient-rb/cache/senders/localhost_repo_cleaner.rb +1 -3
- data/lib/splitclient-rb/cache/stores/sdk_blocker.rb +9 -0
- data/lib/splitclient-rb/clients/split_client.rb +59 -25
- data/lib/splitclient-rb/constants.rb +0 -1
- data/lib/splitclient-rb/engine/api/client.rb +3 -2
- data/lib/splitclient-rb/engine/api/events.rb +10 -1
- data/lib/splitclient-rb/engine/api/impressions.rb +19 -2
- data/lib/splitclient-rb/engine/api/segments.rb +20 -18
- data/lib/splitclient-rb/engine/api/splits.rb +10 -10
- data/lib/splitclient-rb/engine/api/telemetry_api.rb +39 -0
- data/lib/splitclient-rb/engine/auth_api_client.rb +21 -8
- data/lib/splitclient-rb/engine/common/impressions_manager.rb +27 -3
- data/lib/splitclient-rb/engine/metrics/binary_search_latency_tracker.rb +3 -65
- data/lib/splitclient-rb/engine/push_manager.rb +10 -2
- data/lib/splitclient-rb/engine/sync_manager.rb +42 -20
- data/lib/splitclient-rb/engine/synchronizer.rb +14 -22
- data/lib/splitclient-rb/split_config.rb +46 -21
- data/lib/splitclient-rb/split_factory.rb +31 -13
- data/lib/splitclient-rb/split_factory_registry.rb +12 -0
- data/lib/splitclient-rb/sse/event_source/client.rb +15 -1
- data/lib/splitclient-rb/sse/notification_manager_keeper.rb +17 -3
- data/lib/splitclient-rb/sse/sse_handler.rb +10 -6
- data/lib/splitclient-rb/sse/workers/segments_worker.rb +5 -4
- data/lib/splitclient-rb/sse/workers/splits_worker.rb +6 -3
- data/lib/splitclient-rb/telemetry/domain/constants.rb +42 -0
- data/lib/splitclient-rb/telemetry/domain/structs.rb +31 -0
- data/lib/splitclient-rb/telemetry/evaluation_consumer.rb +14 -0
- data/lib/splitclient-rb/telemetry/evaluation_producer.rb +21 -0
- data/lib/splitclient-rb/telemetry/init_consumer.rb +14 -0
- data/lib/splitclient-rb/telemetry/init_producer.rb +19 -0
- data/lib/splitclient-rb/telemetry/memory/memory_evaluation_consumer.rb +32 -0
- data/lib/splitclient-rb/telemetry/memory/memory_evaluation_producer.rb +24 -0
- data/lib/splitclient-rb/telemetry/memory/memory_init_consumer.rb +28 -0
- data/lib/splitclient-rb/telemetry/memory/memory_init_producer.rb +34 -0
- data/lib/splitclient-rb/telemetry/memory/memory_runtime_consumer.rb +112 -0
- data/lib/splitclient-rb/telemetry/memory/memory_runtime_producer.rb +81 -0
- data/lib/splitclient-rb/telemetry/memory/memory_synchronizer.rb +192 -0
- data/lib/splitclient-rb/telemetry/redis/redis_evaluation_producer.rb +38 -0
- data/lib/splitclient-rb/telemetry/redis/redis_init_producer.rb +37 -0
- data/lib/splitclient-rb/telemetry/redis/redis_synchronizer.rb +28 -0
- data/lib/splitclient-rb/telemetry/runtime_consumer.rb +24 -0
- data/lib/splitclient-rb/telemetry/runtime_producer.rb +24 -0
- data/lib/splitclient-rb/telemetry/storages/memory.rb +139 -0
- data/lib/splitclient-rb/telemetry/sync_task.rb +38 -0
- data/lib/splitclient-rb/telemetry/synchronizer.rb +29 -0
- data/lib/splitclient-rb/version.rb +1 -1
- metadata +24 -9
- data/lib/splitclient-rb/cache/repositories/metrics/memory_repository.rb +0 -163
- data/lib/splitclient-rb/cache/repositories/metrics/redis_repository.rb +0 -131
- data/lib/splitclient-rb/cache/repositories/metrics_repository.rb +0 -23
- data/lib/splitclient-rb/cache/senders/metrics_sender.rb +0 -55
- data/lib/splitclient-rb/engine/api/metrics.rb +0 -61
- data/lib/splitclient-rb/engine/metrics/metrics.rb +0 -80
- data/lib/splitclient-rb/redis_metrics_fixer.rb +0 -36
|
@@ -17,7 +17,6 @@ module SplitIoClient
|
|
|
17
17
|
# @option opts [Int] :connection_timeout (2) The connect timeout for network connections in seconds.
|
|
18
18
|
# @option opts [Int] :features_refresh_rate The SDK polls Split servers for changes to feature roll-out plans. This parameter controls this polling period in seconds.
|
|
19
19
|
# @option opts [Int] :segments_refresh_rate
|
|
20
|
-
# @option opts [Int] :metrics_refresh_rate
|
|
21
20
|
# @option opts [Int] :impressions_refresh_rate
|
|
22
21
|
# @option opts [Object] :logger a logger to user for messages from the client. Defaults to stdout
|
|
23
22
|
# @option opts [Boolean] :debug_enabled (false) The value for the debug flag
|
|
@@ -51,7 +50,6 @@ module SplitIoClient
|
|
|
51
50
|
end
|
|
52
51
|
|
|
53
52
|
@segments_refresh_rate = opts[:segments_refresh_rate] || SplitConfig.default_segments_refresh_rate
|
|
54
|
-
@metrics_refresh_rate = opts[:metrics_refresh_rate] || SplitConfig.default_metrics_refresh_rate
|
|
55
53
|
|
|
56
54
|
@impressions_mode = init_impressions_mode(opts[:impressions_mode])
|
|
57
55
|
|
|
@@ -63,10 +61,6 @@ module SplitIoClient
|
|
|
63
61
|
#Safeguard for users of older SDK versions.
|
|
64
62
|
@impressions_bulk_size = opts[:impressions_bulk_size] || @impressions_queue_size > 0 ? @impressions_queue_size : 0
|
|
65
63
|
|
|
66
|
-
@metrics_adapter = SplitConfig.init_cache_adapter(
|
|
67
|
-
opts[:cache_adapter] || SplitConfig.default_cache_adapter, :map_adapter, nil, @redis_url
|
|
68
|
-
)
|
|
69
|
-
|
|
70
64
|
@debug_enabled = opts[:debug_enabled] || SplitConfig.default_debug
|
|
71
65
|
@transport_debug_enabled = opts[:transport_debug_enabled] || SplitConfig.default_debug
|
|
72
66
|
@block_until_ready = SplitConfig.default_block_until_ready
|
|
@@ -97,6 +91,10 @@ module SplitIoClient
|
|
|
97
91
|
opts[:cache_adapter] || SplitConfig.default_cache_adapter, :queue_adapter, @events_queue_size, @redis_url
|
|
98
92
|
)
|
|
99
93
|
|
|
94
|
+
@telemetry_adapter = SplitConfig.init_telemetry_adapter(
|
|
95
|
+
opts[:cache_adapter] || SplitConfig.default_cache_adapter, @redis_url
|
|
96
|
+
)
|
|
97
|
+
|
|
100
98
|
@split_file = opts[:split_file] || SplitConfig.default_split_file
|
|
101
99
|
|
|
102
100
|
@valid_mode = true
|
|
@@ -110,6 +108,11 @@ module SplitIoClient
|
|
|
110
108
|
@auth_retry_back_off_base = SplitConfig.init_auth_retry_back_off(opts[:auth_retry_back_off_base] || SplitConfig.default_auth_retry_back_off_base)
|
|
111
109
|
@streaming_reconnect_back_off_base = SplitConfig.init_streaming_reconnect_back_off(opts[:streaming_reconnect_back_off_base] || SplitConfig.default_streaming_reconnect_back_off_base)
|
|
112
110
|
|
|
111
|
+
@telemetry_refresh_rate = SplitConfig.init_telemetry_refresh_rate(opts[:telemetry_refresh_rate])
|
|
112
|
+
@telemetry_service_url = opts[:telemetry_service_url] || SplitConfig.default_telemetry_service_url
|
|
113
|
+
|
|
114
|
+
@sdk_start_time = Time.now
|
|
115
|
+
|
|
113
116
|
startup_log
|
|
114
117
|
end
|
|
115
118
|
|
|
@@ -148,12 +151,6 @@ module SplitIoClient
|
|
|
148
151
|
# @return [Object] Impressions adapter instance
|
|
149
152
|
attr_accessor :impressions_adapter
|
|
150
153
|
|
|
151
|
-
#
|
|
152
|
-
# The cache adapter to store metrics in
|
|
153
|
-
#
|
|
154
|
-
# @return [Symbol] Metrics adapter
|
|
155
|
-
attr_accessor :metrics_adapter
|
|
156
|
-
|
|
157
154
|
#
|
|
158
155
|
# The cache adapter to store events in
|
|
159
156
|
#
|
|
@@ -224,7 +221,6 @@ module SplitIoClient
|
|
|
224
221
|
|
|
225
222
|
attr_accessor :features_refresh_rate
|
|
226
223
|
attr_accessor :segments_refresh_rate
|
|
227
|
-
attr_accessor :metrics_refresh_rate
|
|
228
224
|
attr_accessor :impressions_refresh_rate
|
|
229
225
|
|
|
230
226
|
attr_accessor :impression_listener
|
|
@@ -274,6 +270,14 @@ module SplitIoClient
|
|
|
274
270
|
|
|
275
271
|
attr_accessor :impressions_mode
|
|
276
272
|
|
|
273
|
+
attr_accessor :telemetry_adapter
|
|
274
|
+
|
|
275
|
+
attr_accessor :telemetry_refresh_rate
|
|
276
|
+
|
|
277
|
+
attr_accessor :telemetry_service_url
|
|
278
|
+
|
|
279
|
+
attr_accessor :sdk_start_time
|
|
280
|
+
|
|
277
281
|
def self.default_impressions_mode
|
|
278
282
|
:optimized
|
|
279
283
|
end
|
|
@@ -296,6 +300,12 @@ module SplitIoClient
|
|
|
296
300
|
return refresh_rate.nil? || refresh_rate <= 0 ? SplitConfig.default_impressions_refresh_rate_optimized : [default_rate, refresh_rate].max
|
|
297
301
|
end
|
|
298
302
|
|
|
303
|
+
def self.init_telemetry_refresh_rate(refresh_rate)
|
|
304
|
+
return SplitConfig.default_telemetry_refresh_rate if refresh_rate.nil? || refresh_rate < 60
|
|
305
|
+
|
|
306
|
+
refresh_rate
|
|
307
|
+
end
|
|
308
|
+
|
|
299
309
|
def self.default_streaming_enabled
|
|
300
310
|
true
|
|
301
311
|
end
|
|
@@ -359,6 +369,21 @@ module SplitIoClient
|
|
|
359
369
|
end
|
|
360
370
|
end
|
|
361
371
|
|
|
372
|
+
def self.init_telemetry_adapter(adapter, redis_url)
|
|
373
|
+
case adapter
|
|
374
|
+
when :memory
|
|
375
|
+
Telemetry::Storages::Memory.new
|
|
376
|
+
when :redis
|
|
377
|
+
begin
|
|
378
|
+
require 'redis'
|
|
379
|
+
rescue LoadError
|
|
380
|
+
fail StandardError, 'To use Redis as a cache adapter you must include it in your Gemfile'
|
|
381
|
+
end
|
|
382
|
+
|
|
383
|
+
SplitIoClient::Cache::Adapters::RedisAdapter.new(redis_url)
|
|
384
|
+
end
|
|
385
|
+
end
|
|
386
|
+
|
|
362
387
|
def self.map_memory_adapter(name, queue_size)
|
|
363
388
|
case name
|
|
364
389
|
when :map_adapter
|
|
@@ -377,10 +402,6 @@ module SplitIoClient
|
|
|
377
402
|
:memory
|
|
378
403
|
end
|
|
379
404
|
|
|
380
|
-
def self.default_metrics_adapter
|
|
381
|
-
:memory
|
|
382
|
-
end
|
|
383
|
-
|
|
384
405
|
#
|
|
385
406
|
# The default read timeout value
|
|
386
407
|
#
|
|
@@ -405,10 +426,6 @@ module SplitIoClient
|
|
|
405
426
|
60
|
|
406
427
|
end
|
|
407
428
|
|
|
408
|
-
def self.default_metrics_refresh_rate
|
|
409
|
-
60
|
|
410
|
-
end
|
|
411
|
-
|
|
412
429
|
def self.default_impressions_refresh_rate
|
|
413
430
|
60
|
|
414
431
|
end
|
|
@@ -433,6 +450,14 @@ module SplitIoClient
|
|
|
433
450
|
500
|
|
434
451
|
end
|
|
435
452
|
|
|
453
|
+
def self.default_telemetry_refresh_rate
|
|
454
|
+
3600
|
|
455
|
+
end
|
|
456
|
+
|
|
457
|
+
def self.default_telemetry_service_url
|
|
458
|
+
'https://telemetry.split.io/api/v1'
|
|
459
|
+
end
|
|
460
|
+
|
|
436
461
|
def self.default_split_file
|
|
437
462
|
File.join(Dir.home, '.split')
|
|
438
463
|
end
|
|
@@ -28,25 +28,25 @@ module SplitIoClient
|
|
|
28
28
|
|
|
29
29
|
raise 'Invalid SDK mode' unless valid_mode
|
|
30
30
|
|
|
31
|
+
build_telemetry_components
|
|
32
|
+
|
|
31
33
|
@splits_repository = SplitsRepository.new(@config)
|
|
32
34
|
@segments_repository = SegmentsRepository.new(@config)
|
|
33
35
|
@impressions_repository = ImpressionsRepository.new(@config)
|
|
34
|
-
@events_repository = EventsRepository.new(@config, @api_key)
|
|
35
|
-
@metrics_repository = MetricsRepository.new(@config)
|
|
36
|
+
@events_repository = EventsRepository.new(@config, @api_key, @runtime_producer)
|
|
36
37
|
@sdk_blocker = SDKBlocker.new(@splits_repository, @segments_repository, @config)
|
|
37
|
-
@metrics = Metrics.new(100, @metrics_repository)
|
|
38
38
|
@impression_counter = SplitIoClient::Engine::Common::ImpressionCounter.new
|
|
39
|
-
@impressions_manager = SplitIoClient::Engine::Common::ImpressionManager.new(@config, @impressions_repository, @impression_counter)
|
|
39
|
+
@impressions_manager = SplitIoClient::Engine::Common::ImpressionManager.new(@config, @impressions_repository, @impression_counter, @runtime_producer)
|
|
40
|
+
@telemetry_api = SplitIoClient::Api::TelemetryApi.new(@config, @api_key, @runtime_producer)
|
|
41
|
+
@telemetry_synchronizer = Telemetry::Synchronizer.new(@config, @telemetry_consumers, @init_producer, repositories, @telemetry_api)
|
|
40
42
|
|
|
41
43
|
start!
|
|
42
44
|
|
|
43
|
-
@client = SplitClient.new(@api_key,
|
|
45
|
+
@client = SplitClient.new(@api_key, repositories, @sdk_blocker, @config, @impressions_manager, @evaluation_producer)
|
|
44
46
|
@manager = SplitManager.new(@splits_repository, @sdk_blocker, @config)
|
|
45
47
|
|
|
46
48
|
validate_api_key
|
|
47
49
|
|
|
48
|
-
RedisMetricsFixer.new(@metrics_repository, @config).call
|
|
49
|
-
|
|
50
50
|
register_factory
|
|
51
51
|
end
|
|
52
52
|
|
|
@@ -54,12 +54,18 @@ module SplitIoClient
|
|
|
54
54
|
if @config.localhost_mode
|
|
55
55
|
start_localhost_components
|
|
56
56
|
else
|
|
57
|
-
split_fetcher = SplitFetcher.new(@splits_repository, @api_key,
|
|
58
|
-
segment_fetcher = SegmentFetcher.new(@segments_repository, @api_key,
|
|
59
|
-
params = {
|
|
57
|
+
split_fetcher = SplitFetcher.new(@splits_repository, @api_key, config, @sdk_blocker, @runtime_producer)
|
|
58
|
+
segment_fetcher = SegmentFetcher.new(@segments_repository, @api_key, config, @sdk_blocker, @runtime_producer)
|
|
59
|
+
params = {
|
|
60
|
+
split_fetcher: split_fetcher,
|
|
61
|
+
segment_fetcher: segment_fetcher,
|
|
62
|
+
imp_counter: @impression_counter,
|
|
63
|
+
telemetry_runtime_producer: @runtime_producer,
|
|
64
|
+
telemetry_synchronizer: @telemetry_synchronizer
|
|
65
|
+
}
|
|
60
66
|
|
|
61
67
|
synchronizer = SplitIoClient::Engine::Synchronizer.new(repositories, @api_key, @config, @sdk_blocker, params)
|
|
62
|
-
SplitIoClient::Engine::SyncManager.new(repositories, @api_key, @config, synchronizer).start
|
|
68
|
+
SplitIoClient::Engine::SyncManager.new(repositories, @api_key, @config, synchronizer, @runtime_producer, @sdk_blocker, @telemetry_synchronizer).start
|
|
63
69
|
end
|
|
64
70
|
end
|
|
65
71
|
|
|
@@ -135,7 +141,6 @@ module SplitIoClient
|
|
|
135
141
|
segments: @segments_repository,
|
|
136
142
|
impressions: @impressions_repository,
|
|
137
143
|
events: @events_repository,
|
|
138
|
-
metrics: @metrics_repository
|
|
139
144
|
}
|
|
140
145
|
end
|
|
141
146
|
|
|
@@ -143,7 +148,20 @@ module SplitIoClient
|
|
|
143
148
|
LocalhostSplitStore.new(@splits_repository, @config, @sdk_blocker).call
|
|
144
149
|
|
|
145
150
|
# Starts thread which loops constantly and cleans up repositories to avoid memory issues in localhost mode
|
|
146
|
-
LocalhostRepoCleaner.new(@impressions_repository, @
|
|
151
|
+
LocalhostRepoCleaner.new(@impressions_repository, @events_repository, @config).call
|
|
147
152
|
end
|
|
153
|
+
|
|
154
|
+
def build_telemetry_components
|
|
155
|
+
@evaluation_consumer = Telemetry::EvaluationConsumer.new(@config)
|
|
156
|
+
@evaluation_producer = Telemetry::EvaluationProducer.new(@config)
|
|
157
|
+
|
|
158
|
+
@init_consumer = Telemetry::InitConsumer.new(@config)
|
|
159
|
+
@init_producer = Telemetry::InitProducer.new(@config)
|
|
160
|
+
|
|
161
|
+
@runtime_consumer = Telemetry::RuntimeConsumer.new(@config)
|
|
162
|
+
@runtime_producer = Telemetry::RuntimeProducer.new(@config)
|
|
163
|
+
|
|
164
|
+
@telemetry_consumers = { init: @init_consumer, evaluation: @evaluation_consumer, runtime: @runtime_consumer }
|
|
165
|
+
end
|
|
148
166
|
end
|
|
149
167
|
end
|
|
@@ -47,5 +47,17 @@ module SplitIoClient
|
|
|
47
47
|
def other_factories
|
|
48
48
|
return !@api_keys_hash.empty?
|
|
49
49
|
end
|
|
50
|
+
|
|
51
|
+
def active_factories
|
|
52
|
+
@api_keys_hash.length
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def redundant_active_factories
|
|
56
|
+
to_return = 0
|
|
57
|
+
|
|
58
|
+
@api_keys_hash.each { |key| to_return += (key[1]-1) }
|
|
59
|
+
|
|
60
|
+
to_return
|
|
61
|
+
end
|
|
50
62
|
end
|
|
51
63
|
end
|
|
@@ -13,7 +13,7 @@ module SplitIoClient
|
|
|
13
13
|
KEEP_ALIVE_RESPONSE = "c\r\n:keepalive\n\n\r\n".freeze
|
|
14
14
|
ERROR_EVENT_TYPE = 'error'.freeze
|
|
15
15
|
|
|
16
|
-
def initialize(config, read_timeout: DEFAULT_READ_TIMEOUT)
|
|
16
|
+
def initialize(config, api_key, telemetry_runtime_producer, read_timeout: DEFAULT_READ_TIMEOUT)
|
|
17
17
|
@config = config
|
|
18
18
|
@read_timeout = read_timeout
|
|
19
19
|
@connected = Concurrent::AtomicBoolean.new(false)
|
|
@@ -21,6 +21,8 @@ module SplitIoClient
|
|
|
21
21
|
@socket = nil
|
|
22
22
|
@event_parser = SSE::EventSource::EventParser.new(config)
|
|
23
23
|
@on = { event: ->(_) {}, action: ->(_) {} }
|
|
24
|
+
@api_key = api_key
|
|
25
|
+
@telemetry_runtime_producer = telemetry_runtime_producer
|
|
24
26
|
|
|
25
27
|
yield self if block_given?
|
|
26
28
|
end
|
|
@@ -43,6 +45,11 @@ module SplitIoClient
|
|
|
43
45
|
end
|
|
44
46
|
|
|
45
47
|
def start(url)
|
|
48
|
+
if connected?
|
|
49
|
+
@config.logger.debug('SSEClient already running.')
|
|
50
|
+
return true
|
|
51
|
+
end
|
|
52
|
+
|
|
46
53
|
@uri = URI(url)
|
|
47
54
|
latch = Concurrent::CountDownLatch.new(1)
|
|
48
55
|
|
|
@@ -111,6 +118,7 @@ module SplitIoClient
|
|
|
111
118
|
|
|
112
119
|
if response_code == OK_CODE && !error_event
|
|
113
120
|
@connected.make_true
|
|
121
|
+
@telemetry_runtime_producer.record_streaming_event(Telemetry::Domain::Constants::SSE_CONNECTION_ESTABLISHED, nil)
|
|
114
122
|
dispatch_action(Constants::PUSH_CONNECTED)
|
|
115
123
|
end
|
|
116
124
|
|
|
@@ -137,6 +145,10 @@ module SplitIoClient
|
|
|
137
145
|
req = "GET #{uri.request_uri} HTTP/1.1\r\n"
|
|
138
146
|
req << "Host: #{uri.host}\r\n"
|
|
139
147
|
req << "Accept: text/event-stream\r\n"
|
|
148
|
+
req << "SplitSDKVersion: #{@config.language}-#{@config.version}\r\n"
|
|
149
|
+
req << "SplitSDKMachineIP: #{@config.machine_ip}\r\n"
|
|
150
|
+
req << "SplitSDKMachineName: #{@config.machine_name}\r\n"
|
|
151
|
+
req << "SplitSDKClientKey: #{@api_key.split(//).last(4).join}\r\n" unless @api_key.nil?
|
|
140
152
|
req << "Cache-Control: no-cache\r\n\r\n"
|
|
141
153
|
@config.logger.debug("Request info: #{req}") if @config.debug_enabled
|
|
142
154
|
req
|
|
@@ -153,6 +165,8 @@ module SplitIoClient
|
|
|
153
165
|
|
|
154
166
|
def dispatch_error(event)
|
|
155
167
|
@config.logger.error("Event error: #{event.event_type}, #{event.data}")
|
|
168
|
+
@telemetry_runtime_producer.record_streaming_event(Telemetry::Domain::Constants::ABLY_ERROR, event.data['code'])
|
|
169
|
+
|
|
156
170
|
if event.data['code'] >= 40_140 && event.data['code'] <= 40_149
|
|
157
171
|
close(Constants::PUSH_RETRYABLE_ERROR)
|
|
158
172
|
elsif event.data['code'] >= 40_000 && event.data['code'] <= 49_999
|
|
@@ -5,12 +5,17 @@ require 'concurrent'
|
|
|
5
5
|
module SplitIoClient
|
|
6
6
|
module SSE
|
|
7
7
|
class NotificationManagerKeeper
|
|
8
|
-
|
|
8
|
+
DISABLED = 0
|
|
9
|
+
ENABLED = 1
|
|
10
|
+
PAUSED = 2
|
|
11
|
+
|
|
12
|
+
def initialize(config, telemetry_runtime_producer)
|
|
9
13
|
@config = config
|
|
10
14
|
@publisher_available = Concurrent::AtomicBoolean.new(true)
|
|
11
15
|
@publishers_pri = Concurrent::AtomicFixnum.new
|
|
12
16
|
@publishers_sec = Concurrent::AtomicFixnum.new
|
|
13
17
|
@on = { action: ->(_) {} }
|
|
18
|
+
@telemetry_runtime_producer = telemetry_runtime_producer
|
|
14
19
|
|
|
15
20
|
yield self if block_given?
|
|
16
21
|
end
|
|
@@ -22,6 +27,7 @@ module SplitIoClient
|
|
|
22
27
|
process_event_occupancy(event.channel, event.data['metrics']['publishers'])
|
|
23
28
|
end
|
|
24
29
|
rescue StandardError => e
|
|
30
|
+
p e
|
|
25
31
|
@config.logger.error(e)
|
|
26
32
|
end
|
|
27
33
|
|
|
@@ -34,10 +40,13 @@ module SplitIoClient
|
|
|
34
40
|
def process_event_control(type)
|
|
35
41
|
case type
|
|
36
42
|
when 'STREAMING_PAUSED'
|
|
43
|
+
@telemetry_runtime_producer.record_streaming_event(Telemetry::Domain::Constants::STREAMING_STATUS, PAUSED)
|
|
37
44
|
dispatch_action(Constants::PUSH_SUBSYSTEM_DOWN)
|
|
38
45
|
when 'STREAMING_RESUMED'
|
|
46
|
+
@telemetry_runtime_producer.record_streaming_event(Telemetry::Domain::Constants::STREAMING_STATUS, ENABLED)
|
|
39
47
|
dispatch_action(Constants::PUSH_SUBSYSTEM_READY) if @publisher_available.value
|
|
40
48
|
when 'STREAMING_DISABLED'
|
|
49
|
+
@telemetry_runtime_producer.record_streaming_event(Telemetry::Domain::Constants::STREAMING_STATUS, DISABLED)
|
|
41
50
|
dispatch_action(Constants::PUSH_SUBSYSTEM_OFF)
|
|
42
51
|
else
|
|
43
52
|
@config.logger.error("Incorrect event type: #{incoming_notification}")
|
|
@@ -59,8 +68,13 @@ module SplitIoClient
|
|
|
59
68
|
end
|
|
60
69
|
|
|
61
70
|
def update_publishers(channel, publishers)
|
|
62
|
-
|
|
63
|
-
|
|
71
|
+
if channel == Constants::CONTROL_PRI
|
|
72
|
+
@telemetry_runtime_producer.record_streaming_event(Telemetry::Domain::Constants::OCCUPANCY_PRI, publishers)
|
|
73
|
+
@publishers_pri.value = publishers
|
|
74
|
+
elsif channel == Constants::CONTROL_SEC
|
|
75
|
+
@telemetry_runtime_producer.record_streaming_event(Telemetry::Domain::Constants::OCCUPANCY_SEC, publishers)
|
|
76
|
+
@publishers_sec.value = publishers
|
|
77
|
+
end
|
|
64
78
|
end
|
|
65
79
|
|
|
66
80
|
def are_publishers_available?
|
|
@@ -5,13 +5,17 @@ module SplitIoClient
|
|
|
5
5
|
class SSEHandler
|
|
6
6
|
attr_reader :sse_client
|
|
7
7
|
|
|
8
|
-
def initialize(
|
|
9
|
-
|
|
8
|
+
def initialize(metadata,
|
|
9
|
+
synchronizer,
|
|
10
|
+
repositories,
|
|
11
|
+
notification_manager_keeper,
|
|
12
|
+
telemetry_runtime_producer)
|
|
13
|
+
@config = metadata[:config]
|
|
10
14
|
@notification_manager_keeper = notification_manager_keeper
|
|
11
|
-
@splits_worker = SplitIoClient::SSE::Workers::SplitsWorker.new(synchronizer, config,
|
|
12
|
-
@segments_worker = SplitIoClient::SSE::Workers::SegmentsWorker.new(synchronizer, config,
|
|
13
|
-
@notification_processor = SplitIoClient::SSE::NotificationProcessor.new(config, @splits_worker, @segments_worker)
|
|
14
|
-
@sse_client = SSE::EventSource::Client.new(@config) do |client|
|
|
15
|
+
@splits_worker = SplitIoClient::SSE::Workers::SplitsWorker.new(synchronizer, @config, repositories[:splits])
|
|
16
|
+
@segments_worker = SplitIoClient::SSE::Workers::SegmentsWorker.new(synchronizer, @config, repositories[:segments])
|
|
17
|
+
@notification_processor = SplitIoClient::SSE::NotificationProcessor.new(@config, @splits_worker, @segments_worker)
|
|
18
|
+
@sse_client = SSE::EventSource::Client.new(@config, metadata[:api_key], telemetry_runtime_producer) do |client|
|
|
15
19
|
client.on_event { |event| handle_incoming_message(event) }
|
|
16
20
|
client.on_action { |action| process_action(action) }
|
|
17
21
|
end
|
|
@@ -48,12 +48,13 @@ module SplitIoClient
|
|
|
48
48
|
def perform
|
|
49
49
|
while (item = @queue.pop)
|
|
50
50
|
segment_name = item[:segment_name]
|
|
51
|
-
|
|
52
|
-
|
|
51
|
+
cn = item[:change_number]
|
|
52
|
+
@config.logger.debug("SegmentsWorker change_number dequeue #{segment_name}, #{cn}")
|
|
53
53
|
|
|
54
|
-
|
|
55
|
-
|
|
54
|
+
attempt = 0
|
|
55
|
+
while cn > @segments_repository.get_change_number(segment_name).to_i && attempt <= Workers::MAX_RETRIES_ALLOWED
|
|
56
56
|
@synchronizer.fetch_segment(segment_name)
|
|
57
|
+
attempt += 1
|
|
57
58
|
end
|
|
58
59
|
end
|
|
59
60
|
end
|
|
@@ -3,6 +3,8 @@
|
|
|
3
3
|
module SplitIoClient
|
|
4
4
|
module SSE
|
|
5
5
|
module Workers
|
|
6
|
+
MAX_RETRIES_ALLOWED = 10
|
|
7
|
+
|
|
6
8
|
class SplitsWorker
|
|
7
9
|
def initialize(synchronizer, config, splits_repository)
|
|
8
10
|
@synchronizer = synchronizer
|
|
@@ -59,11 +61,12 @@ module SplitIoClient
|
|
|
59
61
|
|
|
60
62
|
def perform
|
|
61
63
|
while (change_number = @queue.pop)
|
|
62
|
-
|
|
64
|
+
@config.logger.debug("SplitsWorker change_number dequeue #{change_number}")
|
|
63
65
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
+
attempt = 0
|
|
67
|
+
while change_number > @splits_repository.get_change_number.to_i && attempt <= Workers::MAX_RETRIES_ALLOWED
|
|
66
68
|
@synchronizer.fetch_splits
|
|
69
|
+
attempt += 1
|
|
67
70
|
end
|
|
68
71
|
end
|
|
69
72
|
end
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module SplitIoClient
|
|
4
|
+
module Telemetry
|
|
5
|
+
module Domain
|
|
6
|
+
class Constants
|
|
7
|
+
BUR_TIMEOUT = 'bur_timeout'
|
|
8
|
+
NON_READY_USAGES = 'non_ready_usages'
|
|
9
|
+
|
|
10
|
+
IMPRESSIONS_DROPPED = 'impressions_dropped'
|
|
11
|
+
IMPRESSIONS_DEDUPE = 'impressions_deduped'
|
|
12
|
+
IMPRESSIONS_QUEUED = 'impressions_queued'
|
|
13
|
+
|
|
14
|
+
EVENTS_DROPPED = 'events_dropped'
|
|
15
|
+
EVENTS_QUEUED = 'events_queued'
|
|
16
|
+
|
|
17
|
+
SPLIT_SYNC = 'split_sync'
|
|
18
|
+
SEGMENT_SYNC = 'segment_sync'
|
|
19
|
+
IMPRESSIONS_SYNC = 'impressions_sync'
|
|
20
|
+
IMPRESSION_COUNT_SYNC = 'impression_count_sync'
|
|
21
|
+
EVENT_SYNC = 'event_sync'
|
|
22
|
+
TELEMETRY_SYNC = 'telemetry_sync'
|
|
23
|
+
TOKEN_SYNC = 'token_sync'
|
|
24
|
+
|
|
25
|
+
SSE_CONNECTION_ESTABLISHED = 0
|
|
26
|
+
OCCUPANCY_PRI = 10
|
|
27
|
+
OCCUPANCY_SEC = 20
|
|
28
|
+
STREAMING_STATUS = 30
|
|
29
|
+
CONNECTION_ERROR = 40
|
|
30
|
+
TOKEN_REFRESH = 50
|
|
31
|
+
ABLY_ERROR = 60
|
|
32
|
+
SYNC_MODE = 70
|
|
33
|
+
|
|
34
|
+
TREATMENT = 'treatment'
|
|
35
|
+
TREATMENTS = 'treatments'
|
|
36
|
+
TREATMENT_WITH_CONFIG = 'treatment_with_config'
|
|
37
|
+
TREATMENTS_WITH_CONFIG = 'treatments_with_config'
|
|
38
|
+
TRACK = 'track'
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|