splitclient-rb 7.2.2-java → 7.3.0.pre.rc1-java

Sign up to get free protection for your applications and to get access to all the features.
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 +16 -7
  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 +26 -11
  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,38 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SplitIoClient
4
+ module Telemetry
5
+ class SyncTask
6
+ def initialize(config, telemetry_synchronizer)
7
+ @config = config
8
+ @telemetry_synchronizer = telemetry_synchronizer
9
+ end
10
+
11
+ def call
12
+ stats_thread
13
+
14
+ PhusionPassenger.on_event(:starting_worker_process) { |forked| stats_thread if forked } if defined?(PhusionPassenger)
15
+ end
16
+
17
+ private
18
+
19
+ def stats_thread
20
+ @config.threads[:telemetry_stats_sender] = Thread.new do
21
+ begin
22
+ @config.logger.info('Starting Telemetry Sync Task')
23
+
24
+ loop do
25
+ sleep(@config.telemetry_refresh_rate)
26
+
27
+ @telemetry_synchronizer.synchronize_stats
28
+ end
29
+ rescue SplitIoClient::SDKShutdownException
30
+ @telemetry_synchronizer.synchronize_stats
31
+
32
+ @config.logger.info('Posting Telemetry due to shutdown')
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SplitIoClient
4
+ module Telemetry
5
+ class Synchronizer
6
+ extend Forwardable
7
+ def_delegators :@synchronizer,
8
+ :synchronize_config,
9
+ :synchronize_stats
10
+
11
+ def initialize(config,
12
+ telemtry_consumers,
13
+ telemetry_init_producer,
14
+ repositories,
15
+ telemetry_api)
16
+ @synchronizer = case config.telemetry_adapter.class.to_s
17
+ when 'SplitIoClient::Cache::Adapters::RedisAdapter'
18
+ SplitIoClient::Telemetry::RedisSynchronizer.new(config,
19
+ telemetry_init_producer)
20
+ else
21
+ SplitIoClient::Telemetry::MemorySynchronizer.new(config,
22
+ telemtry_consumers,
23
+ repositories,
24
+ telemetry_api)
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
@@ -1,3 +1,3 @@
1
1
  module SplitIoClient
2
- VERSION = '7.2.2'
2
+ VERSION = '7.3.0.pre.rc1'
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: splitclient-rb
3
3
  version: !ruby/object:Gem::Version
4
- version: 7.2.2
4
+ version: 7.3.0.pre.rc1
5
5
  platform: java
6
6
  authors:
7
7
  - Split Software
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-12-22 00:00:00.000000000 Z
11
+ date: 2021-06-17 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  requirement: !ruby/object:Gem::Requirement
@@ -345,9 +345,6 @@ files:
345
345
  - lib/splitclient-rb/cache/repositories/impressions/memory_repository.rb
346
346
  - lib/splitclient-rb/cache/repositories/impressions/redis_repository.rb
347
347
  - lib/splitclient-rb/cache/repositories/impressions_repository.rb
348
- - lib/splitclient-rb/cache/repositories/metrics/memory_repository.rb
349
- - lib/splitclient-rb/cache/repositories/metrics/redis_repository.rb
350
- - lib/splitclient-rb/cache/repositories/metrics_repository.rb
351
348
  - lib/splitclient-rb/cache/repositories/repository.rb
352
349
  - lib/splitclient-rb/cache/repositories/segments_repository.rb
353
350
  - lib/splitclient-rb/cache/repositories/splits_repository.rb
@@ -357,7 +354,6 @@ files:
357
354
  - lib/splitclient-rb/cache/senders/impressions_formatter.rb
358
355
  - lib/splitclient-rb/cache/senders/impressions_sender.rb
359
356
  - lib/splitclient-rb/cache/senders/localhost_repo_cleaner.rb
360
- - lib/splitclient-rb/cache/senders/metrics_sender.rb
361
357
  - lib/splitclient-rb/cache/stores/localhost_split_builder.rb
362
358
  - lib/splitclient-rb/cache/stores/localhost_split_store.rb
363
359
  - lib/splitclient-rb/cache/stores/sdk_blocker.rb
@@ -369,9 +365,9 @@ files:
369
365
  - lib/splitclient-rb/engine/api/faraday_adapter/patched_net_http_persistent.rb
370
366
  - lib/splitclient-rb/engine/api/faraday_middleware/gzip.rb
371
367
  - lib/splitclient-rb/engine/api/impressions.rb
372
- - lib/splitclient-rb/engine/api/metrics.rb
373
368
  - lib/splitclient-rb/engine/api/segments.rb
374
369
  - lib/splitclient-rb/engine/api/splits.rb
370
+ - lib/splitclient-rb/engine/api/telemetry_api.rb
375
371
  - lib/splitclient-rb/engine/auth_api_client.rb
376
372
  - lib/splitclient-rb/engine/common/impressions_counter.rb
377
373
  - lib/splitclient-rb/engine/common/impressions_manager.rb
@@ -399,7 +395,6 @@ files:
399
395
  - lib/splitclient-rb/engine/matchers/user_defined_segment_matcher.rb
400
396
  - lib/splitclient-rb/engine/matchers/whitelist_matcher.rb
401
397
  - lib/splitclient-rb/engine/metrics/binary_search_latency_tracker.rb
402
- - lib/splitclient-rb/engine/metrics/metrics.rb
403
398
  - lib/splitclient-rb/engine/models/label.rb
404
399
  - lib/splitclient-rb/engine/models/split.rb
405
400
  - lib/splitclient-rb/engine/models/treatment.rb
@@ -412,7 +407,6 @@ files:
412
407
  - lib/splitclient-rb/exceptions.rb
413
408
  - lib/splitclient-rb/helpers/thread_helper.rb
414
409
  - lib/splitclient-rb/managers/split_manager.rb
415
- - lib/splitclient-rb/redis_metrics_fixer.rb
416
410
  - lib/splitclient-rb/split_config.rb
417
411
  - lib/splitclient-rb/split_factory.rb
418
412
  - lib/splitclient-rb/split_factory_builder.rb
@@ -428,6 +422,27 @@ files:
428
422
  - lib/splitclient-rb/sse/sse_handler.rb
429
423
  - lib/splitclient-rb/sse/workers/segments_worker.rb
430
424
  - lib/splitclient-rb/sse/workers/splits_worker.rb
425
+ - lib/splitclient-rb/telemetry/domain/constants.rb
426
+ - lib/splitclient-rb/telemetry/domain/structs.rb
427
+ - lib/splitclient-rb/telemetry/evaluation_consumer.rb
428
+ - lib/splitclient-rb/telemetry/evaluation_producer.rb
429
+ - lib/splitclient-rb/telemetry/init_consumer.rb
430
+ - lib/splitclient-rb/telemetry/init_producer.rb
431
+ - lib/splitclient-rb/telemetry/memory/memory_evaluation_consumer.rb
432
+ - lib/splitclient-rb/telemetry/memory/memory_evaluation_producer.rb
433
+ - lib/splitclient-rb/telemetry/memory/memory_init_consumer.rb
434
+ - lib/splitclient-rb/telemetry/memory/memory_init_producer.rb
435
+ - lib/splitclient-rb/telemetry/memory/memory_runtime_consumer.rb
436
+ - lib/splitclient-rb/telemetry/memory/memory_runtime_producer.rb
437
+ - lib/splitclient-rb/telemetry/memory/memory_synchronizer.rb
438
+ - lib/splitclient-rb/telemetry/redis/redis_evaluation_producer.rb
439
+ - lib/splitclient-rb/telemetry/redis/redis_init_producer.rb
440
+ - lib/splitclient-rb/telemetry/redis/redis_synchronizer.rb
441
+ - lib/splitclient-rb/telemetry/runtime_consumer.rb
442
+ - lib/splitclient-rb/telemetry/runtime_producer.rb
443
+ - lib/splitclient-rb/telemetry/storages/memory.rb
444
+ - lib/splitclient-rb/telemetry/sync_task.rb
445
+ - lib/splitclient-rb/telemetry/synchronizer.rb
431
446
  - lib/splitclient-rb/utilitites.rb
432
447
  - lib/splitclient-rb/validators.rb
433
448
  - lib/splitclient-rb/version.rb
@@ -450,9 +465,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
450
465
  version: '0'
451
466
  required_rubygems_version: !ruby/object:Gem::Requirement
452
467
  requirements:
453
- - - ">="
468
+ - - ">"
454
469
  - !ruby/object:Gem::Version
455
- version: '0'
470
+ version: 1.3.1
456
471
  requirements: []
457
472
  rubyforge_project:
458
473
  rubygems_version: 2.6.14
@@ -1,163 +0,0 @@
1
- require 'concurrent'
2
-
3
- module SplitIoClient
4
- module Cache
5
- module Repositories
6
- module Metrics
7
- class MemoryRepository
8
- OPERATIONS = %w(sdk.get_treatment sdk.get_treatments sdk.get_treatment_with_config sdk.get_treatments_with_config)
9
-
10
- def initialize(_ = nil, config)
11
- @counts = Concurrent::Array.new
12
- @latencies = Concurrent::Array.new
13
- @gauges = Concurrent::Array.new
14
- @config = config
15
- end
16
-
17
- def add_count(counter, delta)
18
- counter_hash = @counts.find { |c| c[:name] == counter }
19
- if counter_hash.nil?
20
- counter_delta = SumAndCount.new
21
- counter_delta.add_delta(delta)
22
- @counts << { name: counter, delta: counter_delta }
23
- else
24
- counter_hash[:delta].add_delta(delta)
25
- end
26
- end
27
-
28
- def add_latency(operation, time_in_ms, binary_search)
29
- if (OPERATIONS.include?(operation))
30
- index = binary_search.add_latency_millis(time_in_ms, true)
31
- increase_latency_bucket(operation, index)
32
- else
33
- concatenate_latency(operation, time_in_ms)
34
- end
35
- end
36
-
37
- def add_gauge(gauge, value)
38
- gauge_hash = @gauges.find { |g| g[:name] == gauge }
39
- if gauge_hash.nil?
40
- gauge_value = ValueAndCount.new
41
- gauge_value.set_value(value)
42
- @gauges << { name: gauge, value: gauge_value }
43
- else
44
- gauge_hash[:value].set_value(value)
45
- end
46
- end
47
-
48
- def counts
49
- @counts.each_with_object({}) do |count, memo|
50
- memo[count[:name]] = count[:delta].sum
51
- end
52
- end
53
-
54
- def latencies
55
- @latencies.each_with_object({}) do |latency, memo|
56
- memo[latency[:operation]] = latency[:latencies]
57
- end
58
- end
59
-
60
- def gauges
61
- # TODO
62
- end
63
-
64
- def fix_latencies
65
- # NOOP
66
- end
67
-
68
- def clear_counts
69
- @counts = Concurrent::Array.new
70
- end
71
-
72
- def clear_latencies
73
- @latencies = Concurrent::Array.new
74
- end
75
-
76
- def clear_gauges
77
- @gauges = Concurrent::Array.new
78
- end
79
-
80
- def clear
81
- clear_counts
82
- clear_latencies
83
- clear_gauges
84
- end
85
-
86
- #
87
- # small class to act as DTO for counts
88
- #
89
- class SumAndCount
90
- attr_reader :count
91
- attr_reader :sum
92
-
93
- def initialize
94
- @count = 0
95
- @sum = 0
96
- end
97
-
98
- def add_delta(delta)
99
- @count += 1
100
- @sum += delta
101
- end
102
-
103
- def clear
104
- @count = 0
105
- @sum = 0
106
- end
107
- end
108
-
109
- #
110
- # small class to act as DTO for gauges
111
- #
112
- class ValueAndCount
113
- attr_reader :count
114
- attr_reader :value
115
-
116
- def initialize
117
- @count = 0
118
- @value = 0
119
- end
120
-
121
- def set_value(value)
122
- @count += 1
123
- @value = value
124
- end
125
-
126
- def clear
127
- @count = 0
128
- @value = 0
129
- end
130
- end
131
-
132
- private
133
-
134
- def increase_latency_bucket(operation, index)
135
- operation_latencies = find_operation_latencies(operation)
136
-
137
- if (operation_latencies.nil?)
138
- latencies_array = Array.new(BinarySearchLatencyTracker::BUCKETS.length, 0)
139
- latencies_array[index] = 1
140
- @latencies << { operation: operation, latencies: latencies_array }
141
- else
142
- operation_latencies[:latencies][index] += 1
143
- end
144
- end
145
-
146
- def concatenate_latency(operation, time_in_ms)
147
- operation_latencies = find_operation_latencies(operation)
148
-
149
- if (operation_latencies.nil?)
150
- @latencies << { operation: operation, latencies: [time_in_ms] }
151
- else
152
- operation_latencies[:latencies].push(time_in_ms)
153
- end
154
- end
155
-
156
- def find_operation_latencies(operation)
157
- @latencies.find { |l| l[:operation] == operation }
158
- end
159
- end
160
- end
161
- end
162
- end
163
- end
@@ -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