splitclient-rb 7.2.3-java → 7.3.0.pre.rc3-java

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 +13 -9
  6. data/lib/splitclient-rb/cache/fetchers/split_fetcher.rb +8 -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
@@ -1,131 +0,0 @@
1
- module SplitIoClient
2
- module Cache
3
- module Repositories
4
- module Metrics
5
- class RedisRepository < Repository
6
- def initialize(config)
7
- @config = config
8
- @adapter = config.metrics_adapter
9
- end
10
-
11
- def add_count(counter, delta)
12
- prefixed_name = impressions_metrics_key("count.#{counter}")
13
- counts = @adapter.find_strings_by_prefix(prefixed_name)
14
-
15
- @adapter.inc(prefixed_name, delta)
16
- end
17
-
18
- def add_latency(operation, time_in_ms, binary_search)
19
- prefixed_name = impressions_metrics_key("latency.#{operation}")
20
-
21
- @adapter.inc("#{prefixed_name}.bucket.#{binary_search.add_latency_millis(time_in_ms, true)}")
22
- end
23
-
24
- def add_gauge(gauge, value)
25
- # TODO
26
- end
27
-
28
- def counts
29
- keys = @adapter.find_strings_by_prefix(impressions_metrics_key("count"))
30
-
31
- return [] if keys.empty?
32
-
33
- @adapter.multiple_strings(keys).map do |name, data|
34
- [name.gsub(impressions_metrics_key('count.'), ''), data]
35
- end.to_h
36
- end
37
-
38
- def latencies
39
- keys = @adapter.find_strings_by_prefix(impressions_metrics_key('latency'))
40
- return [] if keys.empty?
41
-
42
- collected_latencies = collect_latencies(keys)
43
-
44
- collected_latencies.keys.each_with_object({}) do |operation, latencies|
45
- operation_latencies = Array.new(BinarySearchLatencyTracker::BUCKETS.length, 0)
46
- collected_latencies[operation].each do |bucket, value|
47
- operation_latencies[bucket.to_i] = value.to_i
48
- end
49
-
50
- latencies[operation] = operation_latencies
51
- end
52
- end
53
-
54
- def gauges
55
- # TODO
56
- end
57
-
58
- def clear_counts
59
- keys = @adapter.find_strings_by_prefix(impressions_metrics_key('count'))
60
- @adapter.delete(keys)
61
- end
62
-
63
- def clear_latencies
64
- keys = @adapter.find_strings_by_prefix(impressions_metrics_key('latency'))
65
- @adapter.delete(keys)
66
- end
67
-
68
- # introduced to fix incorrect latencies
69
- def fix_latencies
70
- latencies_cleaned_key = namespace_key('/latencies.cleaned')
71
- return if @adapter.exists?(latencies_cleaned_key)
72
-
73
- keys =[]
74
-
75
- 23.times do |index|
76
- keys.concat @adapter.find_strings_by_pattern(latencies_to_be_deleted_key_pattern_prefix("sdk.get_treatment.#{index}"))
77
- end
78
-
79
- keys.concat @adapter.find_strings_by_pattern(latencies_to_be_deleted_key_pattern_prefix('sdk.get_treatments'))
80
- keys.concat @adapter.find_strings_by_pattern(latencies_to_be_deleted_key_pattern_prefix('sdk.get_treatment_with_config'))
81
- keys.concat @adapter.find_strings_by_pattern(latencies_to_be_deleted_key_pattern_prefix('sdk.get_treatments_with_config'))
82
-
83
- keys.concat @adapter.find_strings_by_pattern(latencies_to_be_deleted_key_pattern_prefix('*.time'))
84
-
85
- @config.logger.info("Found incorrect latency keys, deleting. Keys: #{keys}") unless keys.size == 0
86
-
87
- keys.each_slice(500) do |chunk|
88
- @adapter.pipelined do
89
- chunk.each do |key|
90
- @adapter.delete key
91
- end
92
- end
93
- end
94
-
95
- @adapter.set_string(latencies_cleaned_key, '1')
96
- end
97
-
98
- def latencies_to_be_deleted_key_pattern_prefix(key)
99
- "#{@config.redis_namespace}/#{@config.language}-*/latency.#{key}"
100
- end
101
-
102
- def clear_gauges
103
- # TODO
104
- end
105
-
106
- def clear
107
- clear_counts
108
- clear_latencies
109
- clear_gauges
110
- end
111
-
112
- private
113
-
114
- def find_latencies(keys)
115
- @adapter.multiple_strings(keys).map do |name, data|
116
- [name.gsub(impressions_metrics_key('latency.'), ''), data]
117
- end.to_h
118
- end
119
-
120
- def collect_latencies(keys)
121
- find_latencies(keys).each_with_object({}) do |(key, value), collected_latencies|
122
- operation, bucket = key.split('.bucket.')
123
- collected_latencies[operation] = {} unless collected_latencies[operation]
124
- collected_latencies[operation].merge!({bucket => value})
125
- end
126
- end
127
- end
128
- end
129
- end
130
- end
131
- end
@@ -1,23 +0,0 @@
1
- module SplitIoClient
2
- module Cache
3
- module Repositories
4
- # Repository which forwards impressions interface to the selected adapter
5
- class MetricsRepository < Repository
6
- extend Forwardable
7
- def_delegators :@repository, :add_count, :add_latency, :add_gauge, :counts, :latencies, :gauges,
8
- :clear_counts, :clear_latencies, :clear_gauges, :clear, :fix_latencies
9
-
10
- def initialize(config)
11
- super(config)
12
- @repository = case @config.metrics_adapter.class.to_s
13
- when 'SplitIoClient::Cache::Adapters::MemoryAdapter'
14
- Repositories::Metrics::MemoryRepository.new(@config)
15
- when 'SplitIoClient::Cache::Adapters::RedisAdapter'
16
- Repositories::Metrics::RedisRepository.new(@config)
17
- end
18
- end
19
-
20
- end
21
- end
22
- end
23
- end
@@ -1,55 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module SplitIoClient
4
- module Cache
5
- module Senders
6
- class MetricsSender
7
- def initialize(metrics_repository, api_key, config)
8
- @metrics_repository = metrics_repository
9
- @api_key = api_key
10
- @config = config
11
- end
12
-
13
- def call
14
- metrics_thread
15
-
16
- if defined?(PhusionPassenger)
17
- PhusionPassenger.on_event(:starting_worker_process) do |forked|
18
- metrics_thread if forked
19
- end
20
- end
21
- end
22
-
23
- private
24
-
25
- def metrics_thread
26
- @config.threads[:metrics_sender] = Thread.new do
27
- begin
28
- @config.logger.info('Starting metrics service')
29
-
30
- loop do
31
- post_metrics
32
-
33
- sleep(SplitIoClient::Utilities.randomize_interval(@config.metrics_refresh_rate))
34
- end
35
- rescue SplitIoClient::SDKShutdownException
36
- post_metrics
37
-
38
- @config.logger.info('Posting metrics due to shutdown')
39
- end
40
- end
41
- end
42
-
43
- def post_metrics
44
- metrics_api.post
45
- rescue StandardError => error
46
- @config.log_found_exception(__method__.to_s, error)
47
- end
48
-
49
- def metrics_api
50
- @metrics_api ||= SplitIoClient::Api::Metrics.new(@api_key, @metrics_repository, @config)
51
- end
52
- end
53
- end
54
- end
55
- end
@@ -1,61 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module SplitIoClient
4
- module Api
5
- class Metrics < Client
6
- def initialize(api_key, metrics_repository, config)
7
- super(config)
8
- @api_key = api_key
9
- @metrics_repository = metrics_repository
10
- end
11
-
12
- def post
13
- post_latencies
14
- post_counts
15
- end
16
-
17
- private
18
-
19
- def post_latencies
20
- if @metrics_repository.latencies.empty?
21
- @config.split_logger.log_if_debug('No latencies to report.')
22
- else
23
- @metrics_repository.latencies.each do |name, latencies|
24
- metrics_time = { name: name, latencies: latencies }
25
-
26
- response = post_api("#{@config.events_uri}/metrics/time", @api_key, metrics_time)
27
-
28
- log_status(response, metrics_time.size)
29
- end
30
- end
31
-
32
- @metrics_repository.clear_latencies
33
- end
34
-
35
- def post_counts
36
- if @metrics_repository.counts.empty?
37
- @config.split_logger.log_if_debug('No counts to report.')
38
- else
39
- @metrics_repository.counts.each do |name, count|
40
- metrics_count = { name: name, delta: count }
41
-
42
- response = post_api("#{@config.events_uri}/metrics/counter", @api_key, metrics_count)
43
-
44
- log_status(response, metrics_count.size)
45
- end
46
- end
47
- @metrics_repository.clear_counts
48
- end
49
-
50
- def log_status(response, info_to_log)
51
- if response.success?
52
- @config.split_logger.log_if_debug("Metric time reported: #{info_to_log}")
53
- else
54
- @config.logger.error("Unexpected status code while posting time metrics: #{response.status}" \
55
- ' - Check your API key and base URI')
56
- raise 'Split SDK failed to connect to backend to post metrics'
57
- end
58
- end
59
- end
60
- end
61
- end
@@ -1,80 +0,0 @@
1
- module SplitIoClient
2
-
3
- #
4
- # class to handle cached metrics
5
- #
6
- class Metrics < NoMethodError
7
-
8
- @counter
9
- @delta
10
-
11
- #
12
- # cached latencies
13
- #
14
- # @return [object] array of latencies
15
- attr_accessor :latencies
16
-
17
- #
18
- # cached counts
19
- #
20
- # @return [object] array of counts
21
- attr_accessor :counts
22
-
23
- #
24
- # cached gauges
25
- #
26
- # @return [object] array of gauges
27
- attr_accessor :gauges
28
-
29
- #
30
- # quese size for cached arrays
31
- #
32
- # @return [int] queue size
33
- attr_accessor :queue_size
34
-
35
- def initialize(queue_size, repository)
36
- @queue_size = queue_size
37
- @binary_search = SplitIoClient::BinarySearchLatencyTracker.new
38
- @repository = repository
39
- end
40
-
41
- #
42
- # creates a new entry in the array for cached counts
43
- #
44
- # @param counter [string] name of the counter
45
- # @delta [int] value of the counter
46
- #
47
- # @return void
48
- def count(counter, delta)
49
- return if (delta <= 0) || counter.nil? || counter.strip.empty?
50
-
51
- @repository.add_count(counter, delta)
52
- end
53
-
54
- #
55
- # creates a new entry in the array for cached time metrics
56
- #
57
- # @param operation [string] name of the operation
58
- # @time_in_ms [number] time in miliseconds
59
- #
60
- # @return void
61
- def time(operation, time_in_ms)
62
- return if operation.nil? || operation.empty? || time_in_ms < 0
63
-
64
- @repository.add_latency(operation, time_in_ms, @binary_search)
65
- end
66
-
67
- #
68
- # creates a new entry in the array for cached gauges
69
- #
70
- # @param gauge [string] name of the gauge
71
- # @value [number] value of the gauge
72
- #
73
- # @return void
74
- def gauge(gauge, value)
75
- return if gauge.nil? || gauge.empty?
76
-
77
- @repository.add_gauge(gauge, value)
78
- end
79
- end
80
- end
@@ -1,36 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module SplitIoClient
4
- class RedisMetricsFixer
5
- def initialize(metrics_repository, config)
6
- @metrics_repository = metrics_repository
7
- @config = config
8
- end
9
-
10
- def call
11
- return if ENV['SPLITCLIENT_ENV'] == 'test' || @config.mode == :standalone
12
-
13
- fixer_thread
14
-
15
- if defined?(PhusionPassenger)
16
- PhusionPassenger.on_event(:starting_worker_process) do |forked|
17
- fixer_thread if forked
18
- end
19
- end
20
- end
21
-
22
- private
23
-
24
- def fixer_thread
25
- Thread.new do
26
- begin
27
- @config.logger.info('Starting redis metrics fixer')
28
-
29
- @metrics_repository.fix_latencies
30
- rescue StandardError => error
31
- @config.log_found_exception(__method__.to_s, error)
32
- end
33
- end
34
- end
35
- end
36
- end