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
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SplitIoClient
4
+ module Telemetry
5
+ class MemoryInitConsumer < InitConsumer
6
+ DEFAULT_VALUE = 0
7
+
8
+ def initialize(config)
9
+ @config = config
10
+ @adapter = config.telemetry_adapter
11
+ end
12
+
13
+ def non_ready_usages
14
+ find_counts(Domain::Constants::NON_READY_USAGES)
15
+ end
16
+
17
+ def bur_timeouts
18
+ find_counts(Domain::Constants::BUR_TIMEOUT)
19
+ end
20
+
21
+ private
22
+
23
+ def find_counts(action)
24
+ @adapter.factory_counters.find { |l| l[:action] == action }[:counts].value
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SplitIoClient
4
+ module Telemetry
5
+ class MemoryInitProducer < InitProducer
6
+ def initialize(config)
7
+ @config = config
8
+ @adapter = config.telemetry_adapter
9
+ end
10
+
11
+ def record_config
12
+ # no op
13
+ end
14
+
15
+ def record_bur_timeout
16
+ find_factory_counters(Domain::Constants::BUR_TIMEOUT)[:counts].increment
17
+ rescue StandardError => error
18
+ @config.log_found_exception(__method__.to_s, error)
19
+ end
20
+
21
+ def record_non_ready_usages
22
+ find_factory_counters(Domain::Constants::NON_READY_USAGES)[:counts].increment
23
+ rescue StandardError => error
24
+ @config.log_found_exception(__method__.to_s, error)
25
+ end
26
+
27
+ private
28
+
29
+ def find_factory_counters(action)
30
+ @adapter.factory_counters.find { |l| l[:action] == action }
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,112 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SplitIoClient
4
+ module Telemetry
5
+ class MemoryRuntimeConsumer < RuntimeConsumer
6
+ DEFAULT_VALUE = 0
7
+
8
+ def initialize(config)
9
+ @config = config
10
+ @adapter = config.telemetry_adapter
11
+ end
12
+
13
+ def pop_tags
14
+ to_return = @adapter.tags
15
+
16
+ @adapter.init_tags
17
+
18
+ to_return
19
+ end
20
+
21
+ def impressions_stats(type)
22
+ @adapter.impressions_data_records.find { |l| l[:type] == type }[:value].value
23
+ end
24
+
25
+ def events_stats(type)
26
+ @adapter.events_data_records.find { |l| l[:type] == type }[:value].value
27
+ end
28
+
29
+ def last_synchronizations
30
+ splits = find_last_synchronization(Domain::Constants::SPLIT_SYNC)
31
+ segments = find_last_synchronization(Domain::Constants::SEGMENT_SYNC)
32
+ impressions = find_last_synchronization(Domain::Constants::IMPRESSIONS_SYNC)
33
+ imp_count = find_last_synchronization(Domain::Constants::IMPRESSION_COUNT_SYNC)
34
+ events = find_last_synchronization(Domain::Constants::EVENT_SYNC)
35
+ telemetry = find_last_synchronization(Domain::Constants::TELEMETRY_SYNC)
36
+ token = find_last_synchronization(Domain::Constants::TOKEN_SYNC)
37
+
38
+ LastSynchronization.new(splits, segments, impressions, imp_count, events, telemetry, token)
39
+ end
40
+
41
+ def pop_http_errors
42
+ splits = find_http_errors(Domain::Constants::SPLIT_SYNC)
43
+ segments = find_http_errors(Domain::Constants::SEGMENT_SYNC)
44
+ impressions = find_http_errors(Domain::Constants::IMPRESSIONS_SYNC)
45
+ imp_count = find_http_errors(Domain::Constants::IMPRESSION_COUNT_SYNC)
46
+ events = find_http_errors(Domain::Constants::EVENT_SYNC)
47
+ telemetry = find_http_errors(Domain::Constants::TELEMETRY_SYNC)
48
+ token = find_http_errors(Domain::Constants::TOKEN_SYNC)
49
+
50
+ @adapter.init_http_errors
51
+
52
+ HttpErrors.new(splits, segments, impressions, imp_count, events, telemetry, token)
53
+ end
54
+
55
+ def pop_http_latencies
56
+ splits = find_http_latencies(Domain::Constants::SPLIT_SYNC)
57
+ segments = find_http_latencies(Domain::Constants::SEGMENT_SYNC)
58
+ impressions = find_http_latencies(Domain::Constants::IMPRESSIONS_SYNC)
59
+ imp_count = find_http_latencies(Domain::Constants::IMPRESSION_COUNT_SYNC)
60
+ events = find_http_latencies(Domain::Constants::EVENT_SYNC)
61
+ telemetry = find_http_latencies(Domain::Constants::TELEMETRY_SYNC)
62
+ token = find_http_latencies(Domain::Constants::TOKEN_SYNC)
63
+
64
+ @adapter.init_http_latencies
65
+
66
+ HttpLatencies.new(splits, segments, impressions, imp_count, events, telemetry, token)
67
+ end
68
+
69
+ def pop_auth_rejections
70
+ to_return = @adapter.auth_rejections
71
+
72
+ @adapter.init_auth_rejections
73
+
74
+ to_return.value
75
+ end
76
+
77
+ def pop_token_refreshes
78
+ to_return = @adapter.token_refreshes
79
+
80
+ @adapter.init_token_refreshes
81
+
82
+ to_return.value
83
+ end
84
+
85
+ def pop_streaming_events
86
+ events = @adapter.streaming_events
87
+
88
+ @adapter.init_streaming_events.map
89
+
90
+ events
91
+ end
92
+
93
+ def session_length
94
+ @adapter.session_length.value
95
+ end
96
+
97
+ private
98
+
99
+ def find_last_synchronization(type)
100
+ @adapter.last_synchronization.find { |l| l[:type] == type }[:value].value
101
+ end
102
+
103
+ def find_http_errors(type)
104
+ @adapter.http_errors.find { |l| l[:type] == type }[:value]
105
+ end
106
+
107
+ def find_http_latencies(type)
108
+ @adapter.http_latencies.find { |l| l[:type] == type }[:value]
109
+ end
110
+ end
111
+ end
112
+ end
@@ -0,0 +1,81 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SplitIoClient
4
+ module Telemetry
5
+ class MemoryRuntimeProducer < RuntimeProducer
6
+ def initialize(config)
7
+ @config = config
8
+ @adapter = config.telemetry_adapter
9
+ end
10
+
11
+ def add_tag(tag)
12
+ return if tag.length >= 9
13
+
14
+ @adapter.tags << tag
15
+ end
16
+
17
+ def record_impressions_stats(type, count)
18
+ @adapter.impressions_data_records.find { |l| l[:type] == type }[:value].value += count unless count.zero?
19
+ rescue StandardError => error
20
+ @config.log_found_exception(__method__.to_s, error)
21
+ end
22
+
23
+ def record_events_stats(type, count)
24
+ @adapter.events_data_records.find { |l| l[:type] == type }[:value].value += count unless count.zero?
25
+ rescue StandardError => error
26
+ @config.log_found_exception(__method__.to_s, error)
27
+ end
28
+
29
+ def record_successful_sync(type, value = nil)
30
+ value = (Time.now.to_f * 1000.0).to_i if value.nil?
31
+
32
+ @adapter.last_synchronization.find { |l| l[:type] == type }[:value] = Concurrent::AtomicFixnum.new(value)
33
+ rescue StandardError => error
34
+ @config.log_found_exception(__method__.to_s, error)
35
+ end
36
+
37
+ def record_sync_error(type, status)
38
+ http_errors = @adapter.http_errors.find { |l| l[:type] == type }[:value]
39
+
40
+ begin
41
+ http_errors[status] += 1
42
+ rescue StandardError => _
43
+ http_errors[status] = 1
44
+ end
45
+ rescue StandardError => error
46
+ @config.log_found_exception(__method__.to_s, error)
47
+ end
48
+
49
+ def record_sync_latency(type, bucket)
50
+ @adapter.http_latencies.find { |l| l[:type] == type }[:value][bucket] += 1
51
+ rescue StandardError => error
52
+ @config.log_found_exception(__method__.to_s, error)
53
+ end
54
+
55
+ def record_auth_rejections
56
+ @adapter.auth_rejections.increment
57
+ rescue StandardError => error
58
+ @config.log_found_exception(__method__.to_s, error)
59
+ end
60
+
61
+ def record_token_refreshes
62
+ @adapter.token_refreshes.increment
63
+ rescue StandardError => error
64
+ @config.log_found_exception(__method__.to_s, error)
65
+ end
66
+
67
+ def record_streaming_event(type, data = nil, timestamp = nil)
68
+ timestamp ||= (Time.now.to_f * 1000.0).to_i
69
+ @adapter.streaming_events << { e: type, d: data, t: timestamp } unless @adapter.streaming_events.length >= 19
70
+ rescue StandardError => error
71
+ @config.log_found_exception(__method__.to_s, error)
72
+ end
73
+
74
+ def record_session_length(session)
75
+ @adapter.session_length.value = session
76
+ rescue StandardError => error
77
+ @config.log_found_exception(__method__.to_s, error)
78
+ end
79
+ end
80
+ end
81
+ end
@@ -0,0 +1,192 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SplitIoClient
4
+ module Telemetry
5
+ class MemorySynchronizer < Synchronizer
6
+ def initialize(config,
7
+ telemtry_consumers,
8
+ repositories,
9
+ telemetry_api)
10
+ @config = config
11
+ @telemetry_init_consumer = telemtry_consumers[:init]
12
+ @telemetry_runtime_consumer = telemtry_consumers[:runtime]
13
+ @telemtry_evaluation_consumer = telemtry_consumers[:evaluation]
14
+ @splits_repository = repositories[:splits]
15
+ @segments_repository = repositories[:segments]
16
+ @telemetry_api = telemetry_api
17
+ end
18
+
19
+ def synchronize_stats
20
+ usage = Usage.new(@telemetry_runtime_consumer.last_synchronizations,
21
+ @telemtry_evaluation_consumer.pop_latencies,
22
+ @telemtry_evaluation_consumer.pop_exceptions,
23
+ @telemetry_runtime_consumer.pop_http_errors,
24
+ @telemetry_runtime_consumer.pop_http_latencies,
25
+ @telemetry_runtime_consumer.pop_token_refreshes,
26
+ @telemetry_runtime_consumer.pop_auth_rejections,
27
+ @telemetry_runtime_consumer.impressions_stats(Domain::Constants::IMPRESSIONS_QUEUED),
28
+ @telemetry_runtime_consumer.impressions_stats(Domain::Constants::IMPRESSIONS_DEDUPE),
29
+ @telemetry_runtime_consumer.impressions_stats(Domain::Constants::IMPRESSIONS_DROPPED),
30
+ @splits_repository.splits_count,
31
+ @segments_repository.segments_count,
32
+ @segments_repository.segment_keys_count,
33
+ @telemetry_runtime_consumer.session_length,
34
+ @telemetry_runtime_consumer.events_stats(Domain::Constants::EVENTS_QUEUED),
35
+ @telemetry_runtime_consumer.events_stats(Domain::Constants::EVENTS_DROPPED),
36
+ @telemetry_runtime_consumer.pop_streaming_events,
37
+ @telemetry_runtime_consumer.pop_tags)
38
+
39
+ @telemetry_api.record_stats(format_stats(usage))
40
+ rescue StandardError => error
41
+ @config.log_found_exception(__method__.to_s, error)
42
+ end
43
+
44
+ def synchronize_config(active_factories = nil, redundant_active_factories = nil, time_until_ready = nil)
45
+ rates = Rates.new(@config.features_refresh_rate,
46
+ @config.segments_refresh_rate,
47
+ @config.impressions_refresh_rate,
48
+ @config.events_push_rate,
49
+ @config.telemetry_refresh_rate)
50
+
51
+ url_overrides = UrlOverrides.new(@config.base_uri != SplitConfig.default_base_uri.chomp('/'),
52
+ @config.events_uri != SplitConfig.default_events_uri.chomp('/'),
53
+ @config.auth_service_url != SplitConfig.default_auth_service_url,
54
+ @config.streaming_service_url != SplitConfig.default_streaming_service_url,
55
+ @config.telemetry_service_url != SplitConfig.default_telemetry_service_url)
56
+
57
+ active_factories ||= SplitIoClient.split_factory_registry.active_factories
58
+ redundant_active_factories ||= SplitIoClient.split_factory_registry.redundant_active_factories
59
+
60
+ init_config = ConfigInit.new(mode,
61
+ 'memory',
62
+ active_factories,
63
+ redundant_active_factories,
64
+ @telemetry_runtime_consumer.pop_tags,
65
+ @config.streaming_enabled,
66
+ rates,
67
+ url_overrides,
68
+ @config.impressions_queue_size,
69
+ @config.events_queue_size,
70
+ impressions_mode,
71
+ !@config.impression_listener.nil?,
72
+ http_proxy_detected?,
73
+ time_until_ready || Time.now.to_i - @config.sdk_start_time.to_i,
74
+ @telemetry_init_consumer.bur_timeouts,
75
+ @telemetry_init_consumer.non_ready_usages)
76
+
77
+ @telemetry_api.record_init(fornat_init_config(init_config))
78
+ rescue StandardError => error
79
+ @config.log_found_exception(__method__.to_s, error)
80
+ end
81
+
82
+ private
83
+
84
+ def fornat_init_config(init)
85
+ {
86
+ oM: init.om,
87
+ sE: init.se,
88
+ st: init.st,
89
+ rR: {
90
+ sp: init.rr.sp,
91
+ se: init.rr.se,
92
+ im: init.rr.im,
93
+ ev: init.rr.ev,
94
+ te: init.rr.te
95
+ },
96
+ iQ: init.iq,
97
+ eQ: init.eq,
98
+ iM: init.im,
99
+ uO: {
100
+ s: init.uo.s,
101
+ e: init.uo.e,
102
+ a: init.uo.a,
103
+ st: init.uo.st,
104
+ t: init.uo.t
105
+ },
106
+ iL: init.il,
107
+ hP: init.hp,
108
+ aF: init.af,
109
+ rF: init.rf,
110
+ tR: init.tr,
111
+ bT: init.bt,
112
+ nR: init.nr,
113
+ t: init.t,
114
+ i: init.i
115
+ }
116
+ end
117
+
118
+ def format_stats(usage)
119
+ {
120
+ lS: usage.ls.to_h,
121
+ mL: {
122
+ t: usage.ml[Telemetry::Domain::Constants::TREATMENT],
123
+ ts: usage.ml[Telemetry::Domain::Constants::TREATMENTS],
124
+ tc: usage.ml[Telemetry::Domain::Constants::TREATMENT_WITH_CONFIG],
125
+ tcs: usage.ml[Telemetry::Domain::Constants::TREATMENTS_WITH_CONFIG],
126
+ tr: usage.ml[Telemetry::Domain::Constants::TRACK]
127
+ },
128
+ mE: {
129
+ t: usage.me[Telemetry::Domain::Constants::TREATMENT],
130
+ ts: usage.me[Telemetry::Domain::Constants::TREATMENTS],
131
+ tc: usage.me[Telemetry::Domain::Constants::TREATMENT_WITH_CONFIG],
132
+ tcs: usage.me[Telemetry::Domain::Constants::TREATMENTS_WITH_CONFIG],
133
+ tr: usage.me[Telemetry::Domain::Constants::TRACK]
134
+ },
135
+ hE: {
136
+ sp: usage.he.sp,
137
+ se: usage.he.se,
138
+ im: usage.he.im,
139
+ ic: usage.he.ic,
140
+ ev: usage.he.ev,
141
+ te: usage.he.te,
142
+ to: usage.he.to
143
+ },
144
+ hL: {
145
+ sp: usage.hl.sp,
146
+ se: usage.hl.se,
147
+ im: usage.hl.im,
148
+ ic: usage.hl.ic,
149
+ ev: usage.hl.ev,
150
+ te: usage.hl.te,
151
+ to: usage.hl.to
152
+ },
153
+ tR: usage.tr,
154
+ aR: usage.ar,
155
+ iQ: usage.iq,
156
+ iDe: usage.ide,
157
+ iDr: usage.idr,
158
+ spC: usage.spc,
159
+ seC: usage.sec,
160
+ skC: usage.skc,
161
+ sL: usage.sl,
162
+ eQ: usage.eq,
163
+ eD: usage.ed,
164
+ sE: usage.se,
165
+ t: usage.t
166
+ }
167
+ end
168
+
169
+ def http_proxy_detected?
170
+ !ENV['HTTP_PROXY'].nil? || !ENV['HTTPS_PROXY'].nil?
171
+ end
172
+
173
+ def mode
174
+ case @config.mode
175
+ when :customer
176
+ 1
177
+ else
178
+ 0
179
+ end
180
+ end
181
+
182
+ def impressions_mode
183
+ case @config.impressions_mode
184
+ when :optimized
185
+ 0
186
+ else
187
+ 1
188
+ end
189
+ end
190
+ end
191
+ end
192
+ end