splitclient-rb 1.0.2.wip → 8.11.1.pre.rc1-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 (210) hide show
  1. checksums.yaml +5 -5
  2. data/.github/CODEOWNERS +1 -0
  3. data/.github/pull_request_template.md +9 -0
  4. data/.github/workflows/ci.yml +90 -0
  5. data/.github/workflows/update-license-year.yml +45 -0
  6. data/.gitignore +20 -0
  7. data/.rubocop.yml +76 -0
  8. data/.simplecov +1 -0
  9. data/CHANGES.txt +361 -2
  10. data/CONTRIBUTORS-GUIDE.md +49 -0
  11. data/Gemfile +2 -0
  12. data/LICENSE +3 -36
  13. data/NOTICE.txt +5 -0
  14. data/README.md +59 -127
  15. data/Rakefile +27 -3
  16. data/ext/murmurhash/MurmurHash3.java +302 -0
  17. data/gemfiles/faraday_after_0.13.gemfile +7 -0
  18. data/gemfiles/faraday_before_0.13.gemfile +8 -0
  19. data/lib/murmurhash/base.rb +58 -0
  20. data/lib/murmurhash/murmurhash.jar +0 -0
  21. data/lib/murmurhash/murmurhash_mri.rb +3 -0
  22. data/lib/splitclient-rb/cache/adapters/cache_adapter.rb +130 -0
  23. data/lib/splitclient-rb/cache/adapters/memory_adapter.rb +12 -0
  24. data/lib/splitclient-rb/cache/adapters/memory_adapters/map_adapter.rb +137 -0
  25. data/lib/splitclient-rb/cache/adapters/memory_adapters/queue_adapter.rb +53 -0
  26. data/lib/splitclient-rb/cache/adapters/redis_adapter.rb +178 -0
  27. data/lib/splitclient-rb/cache/fetchers/segment_fetcher.rb +83 -0
  28. data/lib/splitclient-rb/cache/fetchers/split_fetcher.rb +70 -0
  29. data/lib/splitclient-rb/cache/filter/bloom_filter.rb +67 -0
  30. data/lib/splitclient-rb/cache/filter/filter_adapter.rb +32 -0
  31. data/lib/splitclient-rb/cache/filter/flag_set_filter.rb +40 -0
  32. data/lib/splitclient-rb/cache/hashers/impression_hasher.rb +34 -0
  33. data/lib/splitclient-rb/cache/observers/impression_observer.rb +22 -0
  34. data/lib/splitclient-rb/cache/observers/noop_impression_observer.rb +10 -0
  35. data/lib/splitclient-rb/cache/repositories/events/memory_repository.rb +45 -0
  36. data/lib/splitclient-rb/cache/repositories/events/redis_repository.rb +35 -0
  37. data/lib/splitclient-rb/cache/repositories/events_repository.rb +61 -0
  38. data/lib/splitclient-rb/cache/repositories/flag_sets/memory_repository.rb +40 -0
  39. data/lib/splitclient-rb/cache/repositories/flag_sets/redis_repository.rb +49 -0
  40. data/lib/splitclient-rb/cache/repositories/impressions/memory_repository.rb +56 -0
  41. data/lib/splitclient-rb/cache/repositories/impressions/redis_repository.rb +57 -0
  42. data/lib/splitclient-rb/cache/repositories/impressions_repository.rb +23 -0
  43. data/lib/splitclient-rb/cache/repositories/repository.rb +24 -0
  44. data/lib/splitclient-rb/cache/repositories/rule_based_segments_repository.rb +136 -0
  45. data/lib/splitclient-rb/cache/repositories/segments_repository.rb +124 -0
  46. data/lib/splitclient-rb/cache/repositories/splits_repository.rb +296 -0
  47. data/lib/splitclient-rb/cache/routers/impression_router.rb +60 -0
  48. data/lib/splitclient-rb/cache/senders/events_sender.rb +42 -0
  49. data/lib/splitclient-rb/cache/senders/impressions_adapter/memory_sender.rb +71 -0
  50. data/lib/splitclient-rb/cache/senders/impressions_adapter/redis_sender.rb +69 -0
  51. data/lib/splitclient-rb/cache/senders/impressions_count_sender.rb +43 -0
  52. data/lib/splitclient-rb/cache/senders/impressions_formatter.rb +95 -0
  53. data/lib/splitclient-rb/cache/senders/impressions_sender.rb +52 -0
  54. data/lib/splitclient-rb/cache/senders/impressions_sender_adapter.rb +21 -0
  55. data/lib/splitclient-rb/cache/senders/localhost_repo_cleaner.rb +47 -0
  56. data/lib/splitclient-rb/cache/stores/localhost_split_builder.rb +95 -0
  57. data/lib/splitclient-rb/cache/stores/localhost_split_store.rb +110 -0
  58. data/lib/splitclient-rb/cache/stores/store_utils.rb +13 -0
  59. data/lib/splitclient-rb/clients/split_client.rb +530 -0
  60. data/lib/splitclient-rb/constants.rb +16 -0
  61. data/lib/splitclient-rb/engine/api/client.rb +87 -0
  62. data/lib/splitclient-rb/engine/api/events.rb +57 -0
  63. data/lib/splitclient-rb/engine/api/faraday_middleware/gzip.rb +58 -0
  64. data/lib/splitclient-rb/engine/api/impressions.rb +79 -0
  65. data/lib/splitclient-rb/engine/api/segments.rb +78 -0
  66. data/lib/splitclient-rb/engine/api/splits.rb +139 -0
  67. data/lib/splitclient-rb/engine/api/telemetry_api.rb +47 -0
  68. data/lib/splitclient-rb/engine/auth_api_client.rb +100 -0
  69. data/lib/splitclient-rb/engine/back_off.rb +26 -0
  70. data/lib/splitclient-rb/engine/common/impressions_counter.rb +45 -0
  71. data/lib/splitclient-rb/engine/common/impressions_manager.rb +165 -0
  72. data/lib/splitclient-rb/engine/common/noop_impressions_counter.rb +27 -0
  73. data/lib/{splitclient-engine → splitclient-rb/engine}/evaluator/splitter.rb +35 -22
  74. data/lib/splitclient-rb/engine/events/events_delivery.rb +20 -0
  75. data/lib/splitclient-rb/engine/events/events_manager.rb +194 -0
  76. data/lib/splitclient-rb/engine/events/events_manager_config.rb +96 -0
  77. data/lib/splitclient-rb/engine/events/events_task.rb +50 -0
  78. data/lib/splitclient-rb/engine/events/noop_events_queue.rb +13 -0
  79. data/lib/splitclient-rb/engine/fallback_treatment_calculator.rb +48 -0
  80. data/lib/splitclient-rb/engine/impressions/noop_unique_keys_tracker.rb +17 -0
  81. data/lib/splitclient-rb/engine/impressions/unique_keys_tracker.rb +144 -0
  82. data/lib/{splitclient-engine → splitclient-rb/engine}/matchers/all_keys_matcher.rb +10 -21
  83. data/lib/splitclient-rb/engine/matchers/between_matcher.rb +47 -0
  84. data/lib/splitclient-rb/engine/matchers/between_semver_matcher.rb +33 -0
  85. data/lib/{splitclient-engine → splitclient-rb/engine}/matchers/combiners.rb +4 -6
  86. data/lib/splitclient-rb/engine/matchers/combining_matcher.rb +80 -0
  87. data/lib/splitclient-rb/engine/matchers/contains_all_matcher.rb +20 -0
  88. data/lib/splitclient-rb/engine/matchers/contains_any_matcher.rb +16 -0
  89. data/lib/splitclient-rb/engine/matchers/contains_matcher.rb +43 -0
  90. data/lib/splitclient-rb/engine/matchers/dependency_matcher.rb +26 -0
  91. data/lib/splitclient-rb/engine/matchers/ends_with_matcher.rb +42 -0
  92. data/lib/splitclient-rb/engine/matchers/equal_to_boolean_matcher.rb +37 -0
  93. data/lib/splitclient-rb/engine/matchers/equal_to_matcher.rb +44 -0
  94. data/lib/splitclient-rb/engine/matchers/equal_to_semver_matcher.rb +28 -0
  95. data/lib/splitclient-rb/engine/matchers/equal_to_set_matcher.rb +16 -0
  96. data/lib/splitclient-rb/engine/matchers/greater_than_or_equal_to_matcher.rb +43 -0
  97. data/lib/splitclient-rb/engine/matchers/greater_than_or_equal_to_semver_matcher.rb +28 -0
  98. data/lib/splitclient-rb/engine/matchers/in_list_semver_matcher.rb +36 -0
  99. data/lib/splitclient-rb/engine/matchers/less_than_or_equal_to_matcher.rb +43 -0
  100. data/lib/splitclient-rb/engine/matchers/less_than_or_equal_to_semver_matcher.rb +28 -0
  101. data/lib/splitclient-rb/engine/matchers/matcher.rb +52 -0
  102. data/lib/splitclient-rb/engine/matchers/matches_string_matcher.rb +29 -0
  103. data/lib/splitclient-rb/engine/matchers/negation_matcher.rb +47 -0
  104. data/lib/splitclient-rb/engine/matchers/part_of_set_matcher.rb +22 -0
  105. data/lib/splitclient-rb/engine/matchers/prerequisites_matcher.rb +31 -0
  106. data/lib/splitclient-rb/engine/matchers/rule_based_segment_matcher.rb +78 -0
  107. data/lib/splitclient-rb/engine/matchers/semver.rb +201 -0
  108. data/lib/splitclient-rb/engine/matchers/set_matcher.rb +27 -0
  109. data/lib/splitclient-rb/engine/matchers/starts_with_matcher.rb +40 -0
  110. data/lib/splitclient-rb/engine/matchers/user_defined_segment_matcher.rb +28 -0
  111. data/lib/splitclient-rb/engine/matchers/whitelist_matcher.rb +66 -0
  112. data/lib/splitclient-rb/engine/metrics/binary_search_latency_tracker.rb +66 -0
  113. data/lib/splitclient-rb/engine/models/evaluation_options.rb +9 -0
  114. data/lib/splitclient-rb/engine/models/event_active_subscriptions.rb +14 -0
  115. data/lib/splitclient-rb/engine/models/events_metadata.rb +10 -0
  116. data/lib/splitclient-rb/engine/models/fallback_treatment.rb +11 -0
  117. data/lib/splitclient-rb/engine/models/fallback_treatments_configuration.rb +36 -0
  118. data/lib/splitclient-rb/engine/models/label.rb +10 -0
  119. data/lib/splitclient-rb/engine/models/sdk_event.rb +4 -0
  120. data/lib/splitclient-rb/engine/models/sdk_event_type.rb +4 -0
  121. data/lib/splitclient-rb/engine/models/sdk_internal_event.rb +8 -0
  122. data/lib/splitclient-rb/engine/models/sdk_internal_event_notification.rb +16 -0
  123. data/lib/splitclient-rb/engine/models/segment_type.rb +4 -0
  124. data/lib/splitclient-rb/engine/models/split.rb +17 -0
  125. data/lib/splitclient-rb/engine/models/split_http_response.rb +19 -0
  126. data/lib/splitclient-rb/engine/models/treatment.rb +3 -0
  127. data/lib/splitclient-rb/engine/models/valid_sdk_event.rb +14 -0
  128. data/lib/splitclient-rb/engine/parser/condition.rb +271 -0
  129. data/lib/splitclient-rb/engine/parser/evaluator.rb +112 -0
  130. data/lib/{splitclient-engine → splitclient-rb/engine}/parser/partition.rb +2 -4
  131. data/lib/splitclient-rb/engine/push_manager.rb +66 -0
  132. data/lib/splitclient-rb/engine/status_manager.rb +39 -0
  133. data/lib/splitclient-rb/engine/sync_manager.rb +183 -0
  134. data/lib/splitclient-rb/engine/synchronizer.rb +231 -0
  135. data/lib/splitclient-rb/exceptions.rb +26 -0
  136. data/lib/splitclient-rb/helpers/decryption_helper.rb +25 -0
  137. data/lib/splitclient-rb/helpers/evaluator_helper.rb +37 -0
  138. data/lib/splitclient-rb/helpers/repository_helper.rb +61 -0
  139. data/lib/splitclient-rb/helpers/thread_helper.rb +24 -0
  140. data/lib/splitclient-rb/helpers/util.rb +26 -0
  141. data/lib/splitclient-rb/managers/split_manager.rb +121 -0
  142. data/lib/splitclient-rb/spec.rb +9 -0
  143. data/lib/splitclient-rb/split_config.rb +591 -47
  144. data/lib/splitclient-rb/split_factory.rb +284 -0
  145. data/lib/splitclient-rb/split_factory_builder.rb +7 -0
  146. data/lib/splitclient-rb/split_factory_registry.rb +63 -0
  147. data/lib/splitclient-rb/split_logger.rb +23 -0
  148. data/lib/splitclient-rb/sse/event_source/client.rb +264 -0
  149. data/lib/splitclient-rb/sse/event_source/event_parser.rb +65 -0
  150. data/lib/splitclient-rb/sse/event_source/event_types.rb +15 -0
  151. data/lib/splitclient-rb/sse/event_source/stream_data.rb +22 -0
  152. data/lib/splitclient-rb/sse/notification_manager_keeper.rb +84 -0
  153. data/lib/splitclient-rb/sse/notification_processor.rb +48 -0
  154. data/lib/splitclient-rb/sse/sse_handler.rb +44 -0
  155. data/lib/splitclient-rb/sse/workers/segments_worker.rb +62 -0
  156. data/lib/splitclient-rb/sse/workers/splits_worker.rb +153 -0
  157. data/lib/splitclient-rb/telemetry/domain/constants.rb +48 -0
  158. data/lib/splitclient-rb/telemetry/domain/structs.rb +35 -0
  159. data/lib/splitclient-rb/telemetry/evaluation_consumer.rb +14 -0
  160. data/lib/splitclient-rb/telemetry/evaluation_producer.rb +21 -0
  161. data/lib/splitclient-rb/telemetry/init_consumer.rb +14 -0
  162. data/lib/splitclient-rb/telemetry/init_producer.rb +19 -0
  163. data/lib/splitclient-rb/telemetry/memory/memory_evaluation_consumer.rb +32 -0
  164. data/lib/splitclient-rb/telemetry/memory/memory_evaluation_producer.rb +24 -0
  165. data/lib/splitclient-rb/telemetry/memory/memory_init_consumer.rb +28 -0
  166. data/lib/splitclient-rb/telemetry/memory/memory_init_producer.rb +34 -0
  167. data/lib/splitclient-rb/telemetry/memory/memory_runtime_consumer.rb +119 -0
  168. data/lib/splitclient-rb/telemetry/memory/memory_runtime_producer.rb +87 -0
  169. data/lib/splitclient-rb/telemetry/memory/memory_synchronizer.rb +213 -0
  170. data/lib/splitclient-rb/telemetry/redis/redis_evaluation_producer.rb +38 -0
  171. data/lib/splitclient-rb/telemetry/redis/redis_init_producer.rb +37 -0
  172. data/lib/splitclient-rb/telemetry/redis/redis_synchronizer.rb +27 -0
  173. data/lib/splitclient-rb/telemetry/runtime_consumer.rb +25 -0
  174. data/lib/splitclient-rb/telemetry/runtime_producer.rb +25 -0
  175. data/lib/splitclient-rb/telemetry/storages/memory.rb +159 -0
  176. data/lib/splitclient-rb/telemetry/sync_task.rb +36 -0
  177. data/lib/splitclient-rb/telemetry/synchronizer.rb +33 -0
  178. data/lib/splitclient-rb/utilitites.rb +49 -0
  179. data/lib/splitclient-rb/validators.rb +361 -0
  180. data/lib/splitclient-rb/version.rb +1 -1
  181. data/lib/splitclient-rb.rb +177 -25
  182. data/sonar-project.properties +6 -0
  183. data/splitclient-rb.gemspec +53 -26
  184. data/tasks/benchmark_get_treatment.rake +31 -17
  185. data/tasks/irb.rake +6 -0
  186. metadata +411 -86
  187. data/NEWS +0 -9
  188. data/lib/splitclient-cache/local_store.rb +0 -45
  189. data/lib/splitclient-engine/impressions/impressions.rb +0 -79
  190. data/lib/splitclient-engine/matchers/between_matcher.rb +0 -48
  191. data/lib/splitclient-engine/matchers/combining_matcher.rb +0 -94
  192. data/lib/splitclient-engine/matchers/equal_to_matcher.rb +0 -48
  193. data/lib/splitclient-engine/matchers/greater_than_or_equal_to_matcher.rb +0 -48
  194. data/lib/splitclient-engine/matchers/less_than_or_equal_to_matcher.rb +0 -48
  195. data/lib/splitclient-engine/matchers/negation_matcher.rb +0 -54
  196. data/lib/splitclient-engine/matchers/user_defined_segment_matcher.rb +0 -61
  197. data/lib/splitclient-engine/matchers/whitelist_matcher.rb +0 -64
  198. data/lib/splitclient-engine/metrics/binary_search_latency_tracker.rb +0 -122
  199. data/lib/splitclient-engine/metrics/metrics.rb +0 -158
  200. data/lib/splitclient-engine/parser/condition.rb +0 -143
  201. data/lib/splitclient-engine/parser/segment.rb +0 -84
  202. data/lib/splitclient-engine/parser/segment_parser.rb +0 -46
  203. data/lib/splitclient-engine/parser/split.rb +0 -68
  204. data/lib/splitclient-engine/parser/split_adapter.rb +0 -433
  205. data/lib/splitclient-engine/parser/split_parser.rb +0 -139
  206. data/lib/splitclient-engine/partitions/treatments.rb +0 -40
  207. data/lib/splitclient-rb/split_client.rb +0 -156
  208. data/lib/splitclient-rb_utilitites.rb +0 -26
  209. data/tasks/console.rake +0 -4
  210. data/tasks/rspec.rake +0 -3
@@ -0,0 +1,32 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SplitIoClient
4
+ module Telemetry
5
+ class MemoryEvaluationConsumer
6
+ def initialize(config)
7
+ @config = config
8
+ @adapter = config.telemetry_adapter
9
+ end
10
+
11
+ def pop_latencies
12
+ to_return = @adapter.latencies.each_with_object({}) do |latency, memo|
13
+ memo[latency[:method]] = latency[:latencies]
14
+ end
15
+
16
+ @adapter.init_latencies
17
+
18
+ to_return
19
+ end
20
+
21
+ def pop_exceptions
22
+ to_return = @adapter.exceptions.each_with_object({}) do |exception, memo|
23
+ memo[exception[:method]] = exception[:exceptions].value
24
+ end
25
+
26
+ @adapter.init_exceptions
27
+
28
+ to_return
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SplitIoClient
4
+ module Telemetry
5
+ class MemoryEvaluationProducer
6
+ def initialize(config)
7
+ @config = config
8
+ @adapter = config.telemetry_adapter
9
+ end
10
+
11
+ def record_latency(method, bucket)
12
+ @adapter.latencies.find { |l| l[:method] == method }[:latencies][bucket] += 1
13
+ rescue StandardError => e
14
+ @config.log_found_exception(__method__.to_s, e)
15
+ end
16
+
17
+ def record_exception(method)
18
+ @adapter.exceptions.find { |l| l[:method] == method }[:exceptions].increment
19
+ rescue StandardError => e
20
+ @config.log_found_exception(__method__.to_s, e)
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SplitIoClient
4
+ module Telemetry
5
+ class MemoryInitConsumer
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
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 => e
18
+ @config.log_found_exception(__method__.to_s, e)
19
+ end
20
+
21
+ def record_non_ready_usages
22
+ find_factory_counters(Domain::Constants::NON_READY_USAGES)[:counts].increment
23
+ rescue StandardError => e
24
+ @config.log_found_exception(__method__.to_s, e)
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,119 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SplitIoClient
4
+ module Telemetry
5
+ class MemoryRuntimeConsumer
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
+ def pop_updates_from_sse
98
+ splits = @adapter.updates_from_sse[Domain::Constants::SPLITS]
99
+ @adapter.updates_from_sse[Domain::Constants::SPLITS] = 0
100
+
101
+ UpdatesFromSSE.new(splits)
102
+ end
103
+
104
+ private
105
+
106
+ def find_last_synchronization(type)
107
+ @adapter.last_synchronization.find { |l| l[:type] == type }[:value].value
108
+ end
109
+
110
+ def find_http_errors(type)
111
+ @adapter.http_errors.find { |l| l[:type] == type }[:value]
112
+ end
113
+
114
+ def find_http_latencies(type)
115
+ @adapter.http_latencies.find { |l| l[:type] == type }[:value]
116
+ end
117
+ end
118
+ end
119
+ end
@@ -0,0 +1,87 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SplitIoClient
4
+ module Telemetry
5
+ class MemoryRuntimeProducer
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 => e
20
+ @config.log_found_exception(__method__.to_s, e)
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 => e
26
+ @config.log_found_exception(__method__.to_s, e)
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 => e
34
+ @config.log_found_exception(__method__.to_s, e)
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 => _e
43
+ http_errors[status] = 1
44
+ end
45
+ rescue StandardError => e
46
+ @config.log_found_exception(__method__.to_s, e)
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 => e
52
+ @config.log_found_exception(__method__.to_s, e)
53
+ end
54
+
55
+ def record_auth_rejections
56
+ @adapter.auth_rejections.increment
57
+ rescue StandardError => e
58
+ @config.log_found_exception(__method__.to_s, e)
59
+ end
60
+
61
+ def record_token_refreshes
62
+ @adapter.token_refreshes.increment
63
+ rescue StandardError => e
64
+ @config.log_found_exception(__method__.to_s, e)
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 => e
71
+ @config.log_found_exception(__method__.to_s, e)
72
+ end
73
+
74
+ def record_session_length(session)
75
+ @adapter.session_length.value = session
76
+ rescue StandardError => e
77
+ @config.log_found_exception(__method__.to_s, e)
78
+ end
79
+
80
+ def record_updates_from_sse(event)
81
+ @adapter.updates_from_sse[event] += 1
82
+ rescue StandardError => e
83
+ @config.log_found_exception(__method__.to_s, e)
84
+ end
85
+ end
86
+ end
87
+ end
@@ -0,0 +1,213 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SplitIoClient
4
+ module Telemetry
5
+ class MemorySynchronizer
6
+ def initialize(config,
7
+ telemtry_consumers,
8
+ repositories,
9
+ telemetry_api,
10
+ flag_sets,
11
+ flag_sets_invalid)
12
+ @config = config
13
+ @telemetry_init_consumer = telemtry_consumers[:init]
14
+ @telemetry_runtime_consumer = telemtry_consumers[:runtime]
15
+ @telemtry_evaluation_consumer = telemtry_consumers[:evaluation]
16
+ @splits_repository = repositories[:splits]
17
+ @segments_repository = repositories[:segments]
18
+ @telemetry_api = telemetry_api
19
+ @flag_sets = flag_sets
20
+ @flag_sets_invalid = flag_sets_invalid
21
+ end
22
+
23
+ def synchronize_stats
24
+ usage = Usage.new(@telemetry_runtime_consumer.last_synchronizations,
25
+ @telemtry_evaluation_consumer.pop_latencies,
26
+ @telemtry_evaluation_consumer.pop_exceptions,
27
+ @telemetry_runtime_consumer.pop_http_errors,
28
+ @telemetry_runtime_consumer.pop_http_latencies,
29
+ @telemetry_runtime_consumer.pop_token_refreshes,
30
+ @telemetry_runtime_consumer.pop_auth_rejections,
31
+ @telemetry_runtime_consumer.impressions_stats(Domain::Constants::IMPRESSIONS_QUEUED),
32
+ @telemetry_runtime_consumer.impressions_stats(Domain::Constants::IMPRESSIONS_DEDUPE),
33
+ @telemetry_runtime_consumer.impressions_stats(Domain::Constants::IMPRESSIONS_DROPPED),
34
+ @splits_repository.splits_count,
35
+ @segments_repository.segments_count,
36
+ @segments_repository.segment_keys_count,
37
+ @telemetry_runtime_consumer.session_length,
38
+ @telemetry_runtime_consumer.events_stats(Domain::Constants::EVENTS_QUEUED),
39
+ @telemetry_runtime_consumer.events_stats(Domain::Constants::EVENTS_DROPPED),
40
+ @telemetry_runtime_consumer.pop_streaming_events,
41
+ @telemetry_runtime_consumer.pop_tags,
42
+ @telemetry_runtime_consumer.pop_updates_from_sse)
43
+
44
+ @telemetry_api.record_stats(format_stats(usage))
45
+ rescue StandardError => e
46
+ @config.log_found_exception(__method__.to_s, e)
47
+ end
48
+
49
+ def synchronize_config(active_factories = nil, redundant_active_factories = nil, time_until_ready = nil)
50
+ rates = Rates.new(@config.features_refresh_rate,
51
+ @config.segments_refresh_rate,
52
+ @config.impressions_refresh_rate,
53
+ @config.events_push_rate,
54
+ @config.telemetry_refresh_rate)
55
+
56
+ url_overrides = UrlOverrides.new(@config.base_uri != SplitConfig.default_base_uri.chomp('/'),
57
+ @config.events_uri != SplitConfig.default_events_uri.chomp('/'),
58
+ @config.auth_service_url != SplitConfig.default_auth_service_url,
59
+ @config.streaming_service_url != SplitConfig.default_streaming_service_url,
60
+ @config.telemetry_service_url != SplitConfig.default_telemetry_service_url)
61
+
62
+ active_factories ||= SplitIoClient.split_factory_registry.active_factories
63
+ redundant_active_factories ||= SplitIoClient.split_factory_registry.redundant_active_factories
64
+ time_until_ready ||= ((Time.now.to_f - @config.sdk_start_time) * 1000.0).to_i
65
+
66
+ init_config = ConfigInit.new(mode,
67
+ 'memory',
68
+ active_factories,
69
+ redundant_active_factories,
70
+ @telemetry_runtime_consumer.pop_tags,
71
+ @flag_sets,
72
+ @flag_sets_invalid,
73
+ @config.streaming_enabled,
74
+ rates,
75
+ url_overrides,
76
+ @config.impressions_queue_size,
77
+ @config.events_queue_size,
78
+ impressions_mode,
79
+ !@config.impression_listener.nil?,
80
+ http_proxy_detected?,
81
+ time_until_ready,
82
+ @telemetry_init_consumer.bur_timeouts,
83
+ @telemetry_init_consumer.non_ready_usages)
84
+
85
+ @telemetry_api.record_init(fornat_init_config(init_config))
86
+ rescue StandardError => e
87
+ @config.log_found_exception(__method__.to_s, e)
88
+ end
89
+
90
+ private
91
+
92
+ def fornat_init_config(init)
93
+ {
94
+ oM: init.om,
95
+ sE: init.se,
96
+ st: init.st,
97
+ rR: {
98
+ sp: init.rr.sp,
99
+ se: init.rr.se,
100
+ im: init.rr.im,
101
+ ev: init.rr.ev,
102
+ te: init.rr.te
103
+ },
104
+ iQ: init.iq,
105
+ eQ: init.eq,
106
+ iM: init.im,
107
+ uO: {
108
+ s: init.uo.s,
109
+ e: init.uo.e,
110
+ a: init.uo.a,
111
+ st: init.uo.st,
112
+ t: init.uo.t
113
+ },
114
+ iL: init.il,
115
+ hP: init.hp,
116
+ aF: init.af,
117
+ rF: init.rf,
118
+ tR: init.tr,
119
+ bT: init.bt,
120
+ nR: init.nr,
121
+ t: init.t,
122
+ i: init.i,
123
+ fsT: init.fsT,
124
+ fsI: init.fsI
125
+ }
126
+ end
127
+
128
+ def format_stats(usage)
129
+ {
130
+ lS: usage.ls.to_h,
131
+ mL: {
132
+ t: usage.ml[Telemetry::Domain::Constants::TREATMENT],
133
+ ts: usage.ml[Telemetry::Domain::Constants::TREATMENTS],
134
+ tc: usage.ml[Telemetry::Domain::Constants::TREATMENT_WITH_CONFIG],
135
+ tcs: usage.ml[Telemetry::Domain::Constants::TREATMENTS_WITH_CONFIG],
136
+ tf: usage.ml[Telemetry::Domain::Constants::TREATMENTS_BY_FLAG_SET],
137
+ tfs: usage.ml[Telemetry::Domain::Constants::TREATMENTS_BY_FLAG_SETS],
138
+ tcf: usage.ml[Telemetry::Domain::Constants::TREATMENTS_WITH_CONFIG_BY_FLAG_SET],
139
+ tcfs: usage.ml[Telemetry::Domain::Constants::TREATMENTS_WITH_CONFIG_BY_FLAG_SETS],
140
+ tr: usage.ml[Telemetry::Domain::Constants::TRACK]
141
+ },
142
+ mE: {
143
+ t: usage.me[Telemetry::Domain::Constants::TREATMENT],
144
+ ts: usage.me[Telemetry::Domain::Constants::TREATMENTS],
145
+ tc: usage.me[Telemetry::Domain::Constants::TREATMENT_WITH_CONFIG],
146
+ tcs: usage.me[Telemetry::Domain::Constants::TREATMENTS_WITH_CONFIG],
147
+ tf: usage.me[Telemetry::Domain::Constants::TREATMENTS_BY_FLAG_SET],
148
+ tfs: usage.me[Telemetry::Domain::Constants::TREATMENTS_BY_FLAG_SETS],
149
+ tcf: usage.me[Telemetry::Domain::Constants::TREATMENTS_WITH_CONFIG_BY_FLAG_SET],
150
+ tcfs: usage.me[Telemetry::Domain::Constants::TREATMENTS_WITH_CONFIG_BY_FLAG_SETS],
151
+ tr: usage.me[Telemetry::Domain::Constants::TRACK]
152
+ },
153
+ hE: {
154
+ sp: usage.he.sp,
155
+ se: usage.he.se,
156
+ im: usage.he.im,
157
+ ic: usage.he.ic,
158
+ ev: usage.he.ev,
159
+ te: usage.he.te,
160
+ to: usage.he.to
161
+ },
162
+ hL: {
163
+ sp: usage.hl.sp,
164
+ se: usage.hl.se,
165
+ im: usage.hl.im,
166
+ ic: usage.hl.ic,
167
+ ev: usage.hl.ev,
168
+ te: usage.hl.te,
169
+ to: usage.hl.to
170
+ },
171
+ tR: usage.tr,
172
+ aR: usage.ar,
173
+ iQ: usage.iq,
174
+ iDe: usage.ide,
175
+ iDr: usage.idr,
176
+ spC: usage.spc,
177
+ seC: usage.sec,
178
+ skC: usage.skc,
179
+ sL: usage.sl,
180
+ eQ: usage.eq,
181
+ eD: usage.ed,
182
+ sE: usage.se,
183
+ t: usage.t,
184
+ ufs: usage.ufs.to_h
185
+ }
186
+ end
187
+
188
+ def http_proxy_detected?
189
+ !ENV['HTTP_PROXY'].nil? || !ENV['HTTPS_PROXY'].nil?
190
+ end
191
+
192
+ def mode
193
+ case @config.mode
194
+ when :customer
195
+ 1
196
+ else
197
+ 0
198
+ end
199
+ end
200
+
201
+ def impressions_mode
202
+ case @config.impressions_mode
203
+ when :optimized
204
+ 0
205
+ when :debug
206
+ 1
207
+ else
208
+ 2
209
+ end
210
+ end
211
+ end
212
+ end
213
+ end
@@ -0,0 +1,38 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SplitIoClient
4
+ module Telemetry
5
+ class RedisEvaluationProducer
6
+ def initialize(config)
7
+ @config = config
8
+ @adapter = config.telemetry_adapter
9
+
10
+ @sdk_version = "#{@config.language}-#{@config.version}"
11
+ @name = @config.machine_name
12
+ @ip = @config.machine_ip
13
+ end
14
+
15
+ def record_latency(method, bucket)
16
+ @adapter.hincrby(latency_key, "#{@sdk_version}/#{@name}/#{@ip}/#{method}/#{bucket}", 1)
17
+ rescue StandardError => e
18
+ @config.log_found_exception(__method__.to_s, e)
19
+ end
20
+
21
+ def record_exception(method)
22
+ @adapter.hincrby(exception_key, "#{@sdk_version}/#{@name}/#{@ip}/#{method}", 1)
23
+ rescue StandardError => e
24
+ @config.log_found_exception(__method__.to_s, e)
25
+ end
26
+
27
+ private
28
+
29
+ def latency_key
30
+ "#{@config.redis_namespace}.telemetry.latencies"
31
+ end
32
+
33
+ def exception_key
34
+ "#{@config.redis_namespace}.telemetry.exceptions"
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,37 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SplitIoClient
4
+ module Telemetry
5
+ class RedisInitProducer
6
+ def initialize(config)
7
+ @config = config
8
+ @adapter = config.telemetry_adapter
9
+ end
10
+
11
+ def record_config(config_data)
12
+ return if config_data.nil?
13
+
14
+ data = { t: { oM: config_data.om, st: config_data.st, aF: config_data.af, rF: config_data.rf, t: config_data.t } }
15
+ field = "#{@config.language}-#{@config.version}/#{@config.machine_name}/#{@config.machine_ip}"
16
+
17
+ @adapter.add_to_map(config_key, field, data.to_json)
18
+ rescue StandardError => e
19
+ @config.log_found_exception(__method__.to_s, e)
20
+ end
21
+
22
+ def record_bur_timeout
23
+ # no-op
24
+ end
25
+
26
+ def record_non_ready_usages
27
+ # no-op
28
+ end
29
+
30
+ private
31
+
32
+ def config_key
33
+ "#{@config.redis_namespace}.telemetry.init"
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SplitIoClient
4
+ module Telemetry
5
+ class RedisSynchronizer
6
+ def initialize(config,
7
+ telemetry_init_producer)
8
+ @config = config
9
+ @telemetry_init_producer = telemetry_init_producer
10
+ end
11
+
12
+ def synchronize_stats
13
+ # No-op
14
+ end
15
+
16
+ def synchronize_config(active_factories = nil, redundant_active_factories = nil, tags = nil)
17
+ active_factories ||= SplitIoClient.split_factory_registry.active_factories
18
+ redundant_active_factories ||= SplitIoClient.split_factory_registry.redundant_active_factories
19
+
20
+ init_config = ConfigInit.new(@config.mode, 'redis', active_factories, redundant_active_factories, tags)
21
+ @telemetry_init_producer.record_config(init_config)
22
+ rescue StandardError => e
23
+ @config.log_found_exception(__method__.to_s, e)
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SplitIoClient
4
+ module Telemetry
5
+ class RuntimeConsumer
6
+ extend Forwardable
7
+ def_delegators :@runtime,
8
+ :pop_tags,
9
+ :impressions_stats,
10
+ :events_stats,
11
+ :last_synchronizations,
12
+ :pop_http_errors,
13
+ :pop_http_latencies,
14
+ :pop_auth_rejections,
15
+ :pop_token_refreshes,
16
+ :pop_streaming_events,
17
+ :session_length,
18
+ :pop_updates_from_sse
19
+
20
+ def initialize(config)
21
+ @runtime = SplitIoClient::Telemetry::MemoryRuntimeConsumer.new(config)
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SplitIoClient
4
+ module Telemetry
5
+ class RuntimeProducer
6
+ extend Forwardable
7
+ def_delegators :@runtime,
8
+ :add_tag,
9
+ :record_impressions_stats,
10
+ :record_events_stats,
11
+ :record_successful_sync,
12
+ :record_sync_error,
13
+ :record_sync_latency,
14
+ :record_auth_rejections,
15
+ :record_token_refreshes,
16
+ :record_streaming_event,
17
+ :record_session_length,
18
+ :record_updates_from_sse
19
+
20
+ def initialize(config)
21
+ @runtime = SplitIoClient::Telemetry::MemoryRuntimeProducer.new(config)
22
+ end
23
+ end
24
+ end
25
+ end