splitclient-rb 6.3.0 → 8.11.0
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/.github/CODEOWNERS +1 -0
- data/.github/pull_request_template.md +9 -0
- data/.github/workflows/ci.yml +90 -0
- data/.github/workflows/update-license-year.yml +45 -0
- data/.gitignore +4 -0
- data/.rubocop.yml +46 -3
- data/CHANGES.txt +158 -11
- data/CONTRIBUTORS-GUIDE.md +49 -0
- data/LICENSE +169 -13
- data/NOTICE.txt +5 -0
- data/README.md +67 -27
- data/Rakefile +1 -8
- data/ext/murmurhash/3_x64_128.c +117 -0
- data/ext/murmurhash/murmurhash.c +5 -1
- data/lib/murmurhash/murmurhash.jar +0 -0
- data/lib/splitclient-rb/cache/adapters/cache_adapter.rb +3 -3
- data/lib/splitclient-rb/cache/adapters/memory_adapters/map_adapter.rb +4 -0
- data/lib/splitclient-rb/cache/adapters/memory_adapters/queue_adapter.rb +7 -0
- data/lib/splitclient-rb/cache/adapters/redis_adapter.rb +12 -4
- data/lib/splitclient-rb/cache/fetchers/segment_fetcher.rb +83 -0
- data/lib/splitclient-rb/cache/fetchers/split_fetcher.rb +70 -0
- data/lib/splitclient-rb/cache/filter/bloom_filter.rb +67 -0
- data/lib/splitclient-rb/cache/filter/filter_adapter.rb +32 -0
- data/lib/splitclient-rb/cache/filter/flag_set_filter.rb +40 -0
- data/lib/splitclient-rb/cache/hashers/impression_hasher.rb +34 -0
- data/lib/splitclient-rb/cache/observers/impression_observer.rb +22 -0
- data/lib/splitclient-rb/cache/observers/noop_impression_observer.rb +10 -0
- data/lib/splitclient-rb/cache/repositories/events/memory_repository.rb +26 -14
- data/lib/splitclient-rb/cache/repositories/events/redis_repository.rb +9 -14
- data/lib/splitclient-rb/cache/repositories/events_repository.rb +31 -10
- data/lib/splitclient-rb/cache/repositories/flag_sets/memory_repository.rb +40 -0
- data/lib/splitclient-rb/cache/repositories/flag_sets/redis_repository.rb +49 -0
- data/lib/splitclient-rb/cache/repositories/impressions/memory_repository.rb +22 -23
- data/lib/splitclient-rb/cache/repositories/impressions/redis_repository.rb +15 -22
- data/lib/splitclient-rb/cache/repositories/impressions_repository.rb +6 -31
- data/lib/splitclient-rb/cache/repositories/repository.rb +6 -5
- data/lib/splitclient-rb/cache/repositories/rule_based_segments_repository.rb +136 -0
- data/lib/splitclient-rb/cache/repositories/segments_repository.rb +46 -6
- data/lib/splitclient-rb/cache/repositories/splits_repository.rb +232 -43
- data/lib/splitclient-rb/cache/routers/impression_router.rb +24 -22
- data/lib/splitclient-rb/cache/senders/events_sender.rb +12 -29
- data/lib/splitclient-rb/cache/senders/impressions_adapter/memory_sender.rb +71 -0
- data/lib/splitclient-rb/cache/senders/impressions_adapter/redis_sender.rb +69 -0
- data/lib/splitclient-rb/cache/senders/impressions_count_sender.rb +43 -0
- data/lib/splitclient-rb/cache/senders/impressions_formatter.rb +27 -13
- data/lib/splitclient-rb/cache/senders/impressions_sender.rb +11 -25
- data/lib/splitclient-rb/cache/senders/impressions_sender_adapter.rb +21 -0
- data/lib/splitclient-rb/cache/senders/localhost_repo_cleaner.rb +47 -0
- data/lib/splitclient-rb/cache/stores/localhost_split_builder.rb +95 -0
- data/lib/splitclient-rb/cache/stores/localhost_split_store.rb +110 -0
- data/lib/splitclient-rb/cache/stores/store_utils.rb +13 -0
- data/lib/splitclient-rb/clients/split_client.rb +385 -138
- data/lib/splitclient-rb/constants.rb +16 -0
- data/lib/splitclient-rb/engine/api/client.rb +38 -43
- data/lib/splitclient-rb/engine/api/events.rb +19 -11
- data/lib/splitclient-rb/engine/api/faraday_middleware/gzip.rb +1 -0
- data/lib/splitclient-rb/engine/api/impressions.rb +49 -14
- data/lib/splitclient-rb/engine/api/segments.rb +31 -24
- data/lib/splitclient-rb/engine/api/splits.rb +108 -33
- data/lib/splitclient-rb/engine/api/telemetry_api.rb +47 -0
- data/lib/splitclient-rb/engine/auth_api_client.rb +96 -0
- data/lib/splitclient-rb/engine/back_off.rb +26 -0
- data/lib/splitclient-rb/engine/common/impressions_counter.rb +45 -0
- data/lib/splitclient-rb/engine/common/impressions_manager.rb +165 -0
- data/lib/splitclient-rb/engine/common/noop_impressions_counter.rb +27 -0
- data/lib/splitclient-rb/engine/events/events_delivery.rb +20 -0
- data/lib/splitclient-rb/engine/events/events_manager.rb +194 -0
- data/lib/splitclient-rb/engine/events/events_manager_config.rb +96 -0
- data/lib/splitclient-rb/engine/events/events_task.rb +50 -0
- data/lib/splitclient-rb/engine/events/noop_events_queue.rb +13 -0
- data/lib/splitclient-rb/engine/fallback_treatment_calculator.rb +48 -0
- data/lib/splitclient-rb/engine/impressions/noop_unique_keys_tracker.rb +17 -0
- data/lib/splitclient-rb/engine/impressions/unique_keys_tracker.rb +144 -0
- data/lib/splitclient-rb/engine/matchers/all_keys_matcher.rb +1 -1
- data/lib/splitclient-rb/engine/matchers/between_matcher.rb +7 -5
- data/lib/splitclient-rb/engine/matchers/between_semver_matcher.rb +33 -0
- data/lib/splitclient-rb/engine/matchers/combining_matcher.rb +10 -8
- data/lib/splitclient-rb/engine/matchers/contains_all_matcher.rb +2 -6
- data/lib/splitclient-rb/engine/matchers/contains_any_matcher.rb +1 -5
- data/lib/splitclient-rb/engine/matchers/contains_matcher.rb +7 -5
- data/lib/splitclient-rb/engine/matchers/dependency_matcher.rb +6 -5
- data/lib/splitclient-rb/engine/matchers/ends_with_matcher.rb +5 -4
- data/lib/splitclient-rb/engine/matchers/equal_to_boolean_matcher.rb +3 -2
- data/lib/splitclient-rb/engine/matchers/equal_to_matcher.rb +6 -4
- data/lib/splitclient-rb/engine/matchers/equal_to_semver_matcher.rb +28 -0
- data/lib/splitclient-rb/engine/matchers/equal_to_set_matcher.rb +1 -5
- data/lib/splitclient-rb/engine/matchers/greater_than_or_equal_to_matcher.rb +6 -4
- data/lib/splitclient-rb/engine/matchers/greater_than_or_equal_to_semver_matcher.rb +28 -0
- data/lib/splitclient-rb/engine/matchers/in_list_semver_matcher.rb +36 -0
- data/lib/splitclient-rb/engine/matchers/less_than_or_equal_to_matcher.rb +6 -4
- data/lib/splitclient-rb/engine/matchers/less_than_or_equal_to_semver_matcher.rb +28 -0
- data/lib/splitclient-rb/engine/matchers/matcher.rb +22 -0
- data/lib/splitclient-rb/engine/matchers/matches_string_matcher.rb +3 -2
- data/lib/splitclient-rb/engine/matchers/negation_matcher.rb +3 -2
- data/lib/splitclient-rb/engine/matchers/part_of_set_matcher.rb +2 -6
- data/lib/splitclient-rb/engine/matchers/prerequisites_matcher.rb +31 -0
- data/lib/splitclient-rb/engine/matchers/rule_based_segment_matcher.rb +78 -0
- data/lib/splitclient-rb/engine/matchers/semver.rb +201 -0
- data/lib/splitclient-rb/engine/matchers/set_matcher.rb +2 -1
- data/lib/splitclient-rb/engine/matchers/starts_with_matcher.rb +4 -3
- data/lib/splitclient-rb/engine/matchers/user_defined_segment_matcher.rb +3 -2
- data/lib/splitclient-rb/engine/matchers/whitelist_matcher.rb +7 -5
- data/lib/splitclient-rb/engine/metrics/binary_search_latency_tracker.rb +3 -65
- data/lib/splitclient-rb/engine/models/evaluation_options.rb +9 -0
- data/lib/splitclient-rb/engine/models/event_active_subscriptions.rb +14 -0
- data/lib/splitclient-rb/engine/models/events_metadata.rb +10 -0
- data/lib/splitclient-rb/engine/models/fallback_treatment.rb +11 -0
- data/lib/splitclient-rb/engine/models/fallback_treatments_configuration.rb +36 -0
- data/lib/splitclient-rb/engine/models/label.rb +3 -0
- data/lib/splitclient-rb/engine/models/sdk_event.rb +4 -0
- data/lib/splitclient-rb/engine/models/sdk_event_type.rb +4 -0
- data/lib/splitclient-rb/engine/models/sdk_internal_event.rb +8 -0
- data/lib/splitclient-rb/engine/models/sdk_internal_event_notification.rb +14 -0
- data/lib/splitclient-rb/engine/models/segment_type.rb +4 -0
- data/lib/splitclient-rb/engine/models/split_http_response.rb +19 -0
- data/lib/splitclient-rb/engine/models/valid_sdk_event.rb +14 -0
- data/lib/splitclient-rb/engine/parser/condition.rb +81 -20
- data/lib/splitclient-rb/engine/parser/evaluator.rb +40 -51
- data/lib/splitclient-rb/engine/push_manager.rb +66 -0
- data/lib/splitclient-rb/engine/status_manager.rb +39 -0
- data/lib/splitclient-rb/engine/sync_manager.rb +180 -0
- data/lib/splitclient-rb/engine/synchronizer.rb +231 -0
- data/lib/splitclient-rb/exceptions.rb +20 -1
- data/lib/splitclient-rb/helpers/decryption_helper.rb +25 -0
- data/lib/splitclient-rb/helpers/evaluator_helper.rb +37 -0
- data/lib/splitclient-rb/helpers/repository_helper.rb +61 -0
- data/lib/splitclient-rb/helpers/thread_helper.rb +24 -0
- data/lib/splitclient-rb/helpers/util.rb +26 -0
- data/lib/splitclient-rb/managers/split_manager.rb +58 -20
- data/lib/splitclient-rb/spec.rb +9 -0
- data/lib/splitclient-rb/split_config.rb +336 -54
- data/lib/splitclient-rb/split_factory.rb +219 -33
- data/lib/splitclient-rb/split_factory_builder.rb +1 -22
- data/lib/splitclient-rb/split_factory_registry.rb +63 -0
- data/lib/splitclient-rb/split_logger.rb +9 -10
- data/lib/splitclient-rb/sse/event_source/client.rb +263 -0
- data/lib/splitclient-rb/sse/event_source/event_parser.rb +65 -0
- data/lib/splitclient-rb/sse/event_source/event_types.rb +15 -0
- data/lib/splitclient-rb/sse/event_source/stream_data.rb +22 -0
- data/lib/splitclient-rb/sse/notification_manager_keeper.rb +84 -0
- data/lib/splitclient-rb/sse/notification_processor.rb +48 -0
- data/lib/splitclient-rb/sse/sse_handler.rb +44 -0
- data/lib/splitclient-rb/sse/workers/segments_worker.rb +62 -0
- data/lib/splitclient-rb/sse/workers/splits_worker.rb +149 -0
- data/lib/splitclient-rb/telemetry/domain/constants.rb +48 -0
- data/lib/splitclient-rb/telemetry/domain/structs.rb +35 -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 +119 -0
- data/lib/splitclient-rb/telemetry/memory/memory_runtime_producer.rb +87 -0
- data/lib/splitclient-rb/telemetry/memory/memory_synchronizer.rb +213 -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 +27 -0
- data/lib/splitclient-rb/telemetry/runtime_consumer.rb +25 -0
- data/lib/splitclient-rb/telemetry/runtime_producer.rb +25 -0
- data/lib/splitclient-rb/telemetry/storages/memory.rb +159 -0
- data/lib/splitclient-rb/telemetry/sync_task.rb +36 -0
- data/lib/splitclient-rb/telemetry/synchronizer.rb +33 -0
- data/lib/splitclient-rb/utilitites.rb +8 -0
- data/lib/splitclient-rb/validators.rb +142 -38
- data/lib/splitclient-rb/version.rb +1 -1
- data/lib/splitclient-rb.rb +101 -16
- data/sonar-project.properties +6 -0
- data/splitclient-rb.gemspec +28 -23
- metadata +262 -82
- data/.travis.yml +0 -11
- data/Appraisals +0 -10
- data/Detailed-README.md +0 -588
- data/NEWS +0 -141
- data/lib/splitclient-rb/cache/repositories/metrics/memory_repository.rb +0 -127
- data/lib/splitclient-rb/cache/repositories/metrics/redis_repository.rb +0 -96
- data/lib/splitclient-rb/cache/repositories/metrics_repository.rb +0 -21
- data/lib/splitclient-rb/cache/senders/metrics_sender.rb +0 -56
- data/lib/splitclient-rb/cache/stores/sdk_blocker.rb +0 -46
- data/lib/splitclient-rb/cache/stores/segment_store.rb +0 -81
- data/lib/splitclient-rb/cache/stores/split_store.rb +0 -102
- data/lib/splitclient-rb/clients/localhost_split_client.rb +0 -183
- data/lib/splitclient-rb/engine/api/faraday_adapter/patched_net_http_persistent.rb +0 -46
- data/lib/splitclient-rb/engine/api/metrics.rb +0 -60
- data/lib/splitclient-rb/engine/metrics/metrics.rb +0 -80
- data/lib/splitclient-rb/engine/parser/split_adapter.rb +0 -81
- data/lib/splitclient-rb/localhost_split_factory.rb +0 -13
- data/lib/splitclient-rb/localhost_utils.rb +0 -59
- data/lib/splitclient-rb/managers/localhost_split_manager.rb +0 -60
|
@@ -42,75 +42,13 @@ module SplitIoClient
|
|
|
42
42
|
|
|
43
43
|
MAX_LATENCY = 7481828
|
|
44
44
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
def initialize
|
|
48
|
-
@latencies = Array.new(BUCKETS.length, 0)
|
|
49
|
-
end
|
|
50
|
-
|
|
51
|
-
#
|
|
52
|
-
# Increment the internal counter for the bucket this latency falls into.
|
|
53
|
-
# @param millis
|
|
54
|
-
#
|
|
55
|
-
def add_latency_millis(millis, return_index = false)
|
|
56
|
-
index = find_bucket_index(millis * 1000)
|
|
57
|
-
|
|
58
|
-
return index if return_index
|
|
59
|
-
|
|
60
|
-
@latencies[index] += 1
|
|
61
|
-
@latencies
|
|
62
|
-
end
|
|
63
|
-
|
|
64
|
-
# Increment the internal counter for the bucket this latency falls into.
|
|
65
|
-
# @param micros
|
|
66
|
-
def add_latency_micros(micros, return_index = false)
|
|
67
|
-
index = find_bucket_index(micros)
|
|
68
|
-
|
|
69
|
-
return index if return_index
|
|
70
|
-
|
|
71
|
-
@latencies[index] += 1
|
|
72
|
-
@latencies
|
|
73
|
-
end
|
|
74
|
-
|
|
75
|
-
# Returns the list of latencies buckets as an array.
|
|
76
|
-
#
|
|
77
|
-
#
|
|
78
|
-
# @return the list of latencies buckets as an array.
|
|
79
|
-
def get_latencies
|
|
80
|
-
@latencies
|
|
81
|
-
end
|
|
82
|
-
|
|
83
|
-
def get_latency(index)
|
|
84
|
-
return @latencies[index]
|
|
85
|
-
end
|
|
86
|
-
|
|
87
|
-
def clear
|
|
88
|
-
@latencies = Array.new(BUCKETS.length, 0)
|
|
89
|
-
end
|
|
90
|
-
|
|
91
|
-
#
|
|
92
|
-
# Returns the counts in the bucket this latency falls into.
|
|
93
|
-
# The latencies will not be updated.
|
|
94
|
-
# @param latency
|
|
95
|
-
# @return the bucket content for the latency.
|
|
96
|
-
#
|
|
97
|
-
def get_bucket_for_latency_millis(latency)
|
|
98
|
-
return @latencies[find_bucket_index(latency * 1000)]
|
|
99
|
-
end
|
|
100
|
-
|
|
101
|
-
#
|
|
102
|
-
# Returns the counts in the bucket this latency falls into.
|
|
103
|
-
# The latencies will not be updated.
|
|
104
|
-
# @param latency
|
|
105
|
-
# @return the bucket content for the latency.
|
|
106
|
-
#
|
|
107
|
-
def get_bucket_for_latency_micros(latency)
|
|
108
|
-
return @latencies[find_bucket_index(latency)]
|
|
45
|
+
def self.get_bucket(latency)
|
|
46
|
+
return find_bucket_index(latency * 1000)
|
|
109
47
|
end
|
|
110
48
|
|
|
111
49
|
private
|
|
112
50
|
|
|
113
|
-
def find_bucket_index(micros)
|
|
51
|
+
def self.find_bucket_index(micros)
|
|
114
52
|
if (micros > MAX_LATENCY) then
|
|
115
53
|
return BUCKETS.length - 1
|
|
116
54
|
end
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# frozen_string_literal: false
|
|
2
|
+
|
|
3
|
+
module SplitIoClient
|
|
4
|
+
module Engine::Models
|
|
5
|
+
class EventActiveSubscriptions
|
|
6
|
+
attr_accessor :triggered, :handler
|
|
7
|
+
|
|
8
|
+
def initialize(triggered, handler)
|
|
9
|
+
@triggered = triggered
|
|
10
|
+
@handler = handler
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
module SplitIoClient::Engine::Models
|
|
2
|
+
class FallbackTreatmentsConfiguration
|
|
3
|
+
attr_accessor :global_fallback_treatment, :by_flag_fallback_treatment
|
|
4
|
+
|
|
5
|
+
def initialize(global_fallback_treatment=nil, by_flag_fallback_treatment=nil)
|
|
6
|
+
@global_fallback_treatment = build_global_fallback_treatment(global_fallback_treatment)
|
|
7
|
+
@by_flag_fallback_treatment = build_by_flag_fallback_treatment(by_flag_fallback_treatment)
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
private
|
|
11
|
+
|
|
12
|
+
def build_global_fallback_treatment(global_fallback_treatment)
|
|
13
|
+
if global_fallback_treatment.is_a? String
|
|
14
|
+
return FallbackTreatment.new(global_fallback_treatment)
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
global_fallback_treatment
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def build_by_flag_fallback_treatment(by_flag_fallback_treatment)
|
|
21
|
+
return nil unless by_flag_fallback_treatment.is_a?(Hash)
|
|
22
|
+
processed_by_flag_fallback_treatment = Hash.new
|
|
23
|
+
|
|
24
|
+
by_flag_fallback_treatment.each do |key, value|
|
|
25
|
+
if value.is_a? String
|
|
26
|
+
processed_by_flag_fallback_treatment[key] = FallbackTreatment.new(value)
|
|
27
|
+
next
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
processed_by_flag_fallback_treatment[key] = value
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
processed_by_flag_fallback_treatment
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
@@ -4,4 +4,7 @@ class SplitIoClient::Engine::Models::Label
|
|
|
4
4
|
EXCEPTION = 'exception'.freeze
|
|
5
5
|
KILLED = 'killed'.freeze
|
|
6
6
|
NOT_IN_SPLIT = 'not in split'.freeze
|
|
7
|
+
NOT_READY = 'not ready'.freeze
|
|
8
|
+
NOT_FOUND = 'definition not found'.freeze
|
|
9
|
+
PREREQUISITES_NOT_MET = 'prerequisites not met'.freeze
|
|
7
10
|
end
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
class SplitIoClient::Engine::Models::SdkInternalEvent
|
|
2
|
+
SDK_READY = 'SDK_READY'
|
|
3
|
+
FLAGS_UPDATED = 'FLAGS_UPDATED'
|
|
4
|
+
FLAG_KILLED_NOTIFICATION = 'FLAG_KILLED_NOTIFICATION'
|
|
5
|
+
SEGMENTS_UPDATED = 'SEGMENTS_UPDATED'
|
|
6
|
+
RB_SEGMENTS_UPDATED = 'RB_SEGMENTS_UPDATED'
|
|
7
|
+
LARGE_SEGMENTS_UPDATED = 'LARGE_SEGMENTS_UPDATED'
|
|
8
|
+
end
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# frozen_string_literal: false
|
|
2
|
+
|
|
3
|
+
module SplitIoClient
|
|
4
|
+
module Engine::Models
|
|
5
|
+
class SdkInternalEventNotification
|
|
6
|
+
attr_reader :internal_event, :metadata
|
|
7
|
+
|
|
8
|
+
def initialize(internal_event, metadata)
|
|
9
|
+
@internal_event = internal_event
|
|
10
|
+
@metadata = metadata
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
module SplitIoClient
|
|
2
|
+
module Engine
|
|
3
|
+
module Models
|
|
4
|
+
class SplitHttpResponse
|
|
5
|
+
attr_accessor :status, :body
|
|
6
|
+
|
|
7
|
+
def initialize(status, body, success)
|
|
8
|
+
@status = status
|
|
9
|
+
@body = body
|
|
10
|
+
@success = success
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def success?
|
|
14
|
+
@success
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
@@ -11,13 +11,14 @@ module SplitIoClient
|
|
|
11
11
|
# @returns [object] condition values
|
|
12
12
|
attr_accessor :data
|
|
13
13
|
|
|
14
|
-
def initialize(condition)
|
|
14
|
+
def initialize(condition, config)
|
|
15
15
|
@data = condition
|
|
16
16
|
@partitions = set_partitions
|
|
17
|
+
@config = config
|
|
17
18
|
end
|
|
18
19
|
|
|
19
20
|
def create_condition_matcher(matchers)
|
|
20
|
-
CombiningMatcher.new(combiner, matchers) if combiner
|
|
21
|
+
CombiningMatcher.new(@config.split_logger, combiner, matchers) if combiner
|
|
21
22
|
end
|
|
22
23
|
|
|
23
24
|
#
|
|
@@ -45,11 +46,11 @@ module SplitIoClient
|
|
|
45
46
|
end
|
|
46
47
|
|
|
47
48
|
def negation_matcher(matcher)
|
|
48
|
-
NegationMatcher.new(matcher)
|
|
49
|
+
NegationMatcher.new(@config.split_logger, matcher)
|
|
49
50
|
end
|
|
50
51
|
|
|
51
52
|
def matcher_all_keys(_params)
|
|
52
|
-
@matcher_all_keys ||= AllKeysMatcher.new
|
|
53
|
+
@matcher_all_keys ||= AllKeysMatcher.new(@config.split_logger)
|
|
53
54
|
end
|
|
54
55
|
|
|
55
56
|
# returns UserDefinedSegmentMatcher[object]
|
|
@@ -57,7 +58,7 @@ module SplitIoClient
|
|
|
57
58
|
matcher = params[:matcher]
|
|
58
59
|
segment_name = matcher[:userDefinedSegmentMatcherData] && matcher[:userDefinedSegmentMatcherData][:segmentName]
|
|
59
60
|
|
|
60
|
-
UserDefinedSegmentMatcher.new(params[:segments_repository], segment_name)
|
|
61
|
+
UserDefinedSegmentMatcher.new(params[:segments_repository], segment_name, @config.split_logger)
|
|
61
62
|
end
|
|
62
63
|
|
|
63
64
|
# returns WhitelistMatcher[object] the whitelist for this condition in case it has a whitelist matcher
|
|
@@ -72,7 +73,7 @@ module SplitIoClient
|
|
|
72
73
|
white_list = (matcher[:whitelistMatcherData])[:whitelist]
|
|
73
74
|
result = { attribute: attribute, value: white_list }
|
|
74
75
|
end
|
|
75
|
-
WhitelistMatcher.new(result)
|
|
76
|
+
WhitelistMatcher.new(result, @config.split_logger, @config.split_validator)
|
|
76
77
|
end
|
|
77
78
|
|
|
78
79
|
def matcher_equal_to(params)
|
|
@@ -80,7 +81,7 @@ module SplitIoClient
|
|
|
80
81
|
attribute = (matcher[:keySelector])[:attribute]
|
|
81
82
|
value = (matcher[:unaryNumericMatcherData])[:value]
|
|
82
83
|
data_type = (matcher[:unaryNumericMatcherData])[:dataType]
|
|
83
|
-
EqualToMatcher.new(attribute: attribute, value: value, data_type: data_type)
|
|
84
|
+
EqualToMatcher.new({attribute: attribute, value: value, data_type: data_type}, @config.split_logger, @config.split_validator)
|
|
84
85
|
end
|
|
85
86
|
|
|
86
87
|
def matcher_greater_than_or_equal_to(params)
|
|
@@ -88,7 +89,7 @@ module SplitIoClient
|
|
|
88
89
|
attribute = (matcher[:keySelector])[:attribute]
|
|
89
90
|
value = (matcher[:unaryNumericMatcherData])[:value]
|
|
90
91
|
data_type = (matcher[:unaryNumericMatcherData])[:dataType]
|
|
91
|
-
GreaterThanOrEqualToMatcher.new(attribute: attribute, value: value, data_type: data_type)
|
|
92
|
+
GreaterThanOrEqualToMatcher.new({attribute: attribute, value: value, data_type: data_type}, @config.split_logger, @config.split_validator)
|
|
92
93
|
end
|
|
93
94
|
|
|
94
95
|
def matcher_less_than_or_equal_to(params)
|
|
@@ -96,7 +97,7 @@ module SplitIoClient
|
|
|
96
97
|
attribute = (matcher[:keySelector])[:attribute]
|
|
97
98
|
value = (matcher[:unaryNumericMatcherData])[:value]
|
|
98
99
|
data_type = (matcher[:unaryNumericMatcherData])[:dataType]
|
|
99
|
-
LessThanOrEqualToMatcher.new(attribute: attribute, value: value, data_type: data_type)
|
|
100
|
+
LessThanOrEqualToMatcher.new({attribute: attribute, value: value, data_type: data_type}, @config.split_logger, @config.split_validator)
|
|
100
101
|
end
|
|
101
102
|
|
|
102
103
|
def matcher_between(params)
|
|
@@ -105,79 +106,137 @@ module SplitIoClient
|
|
|
105
106
|
start_value = (matcher[:betweenMatcherData])[:start]
|
|
106
107
|
end_value = (matcher[:betweenMatcherData])[:end]
|
|
107
108
|
data_type = (matcher[:betweenMatcherData])[:dataType]
|
|
108
|
-
BetweenMatcher.new(attribute: attribute, start_value: start_value, end_value: end_value, data_type: data_type)
|
|
109
|
+
BetweenMatcher.new({attribute: attribute, start_value: start_value, end_value: end_value, data_type: data_type}, @config.split_logger, @config.split_validator)
|
|
109
110
|
end
|
|
110
111
|
|
|
111
112
|
def matcher_equal_to_set(params)
|
|
112
113
|
EqualToSetMatcher.new(
|
|
113
114
|
params[:matcher][:keySelector][:attribute],
|
|
114
|
-
params[:matcher][:whitelistMatcherData][:whitelist]
|
|
115
|
+
params[:matcher][:whitelistMatcherData][:whitelist],
|
|
116
|
+
@config.split_logger
|
|
115
117
|
)
|
|
116
118
|
end
|
|
117
119
|
|
|
118
120
|
def matcher_contains_any_of_set(params)
|
|
119
121
|
ContainsAnyMatcher.new(
|
|
120
122
|
params[:matcher][:keySelector][:attribute],
|
|
121
|
-
params[:matcher][:whitelistMatcherData][:whitelist]
|
|
123
|
+
params[:matcher][:whitelistMatcherData][:whitelist],
|
|
124
|
+
@config.split_logger
|
|
122
125
|
)
|
|
123
126
|
end
|
|
124
127
|
|
|
125
128
|
def matcher_contains_all_of_set(params)
|
|
126
129
|
ContainsAllMatcher.new(
|
|
127
130
|
params[:matcher][:keySelector][:attribute],
|
|
128
|
-
params[:matcher][:whitelistMatcherData][:whitelist]
|
|
131
|
+
params[:matcher][:whitelistMatcherData][:whitelist],
|
|
132
|
+
@config.split_logger
|
|
129
133
|
)
|
|
130
134
|
end
|
|
131
135
|
|
|
132
136
|
def matcher_part_of_set(params)
|
|
133
137
|
PartOfSetMatcher.new(
|
|
134
138
|
params[:matcher][:keySelector][:attribute],
|
|
135
|
-
params[:matcher][:whitelistMatcherData][:whitelist]
|
|
139
|
+
params[:matcher][:whitelistMatcherData][:whitelist],
|
|
140
|
+
@config.split_logger
|
|
136
141
|
)
|
|
137
142
|
end
|
|
138
143
|
|
|
139
144
|
def matcher_starts_with(params)
|
|
140
145
|
StartsWithMatcher.new(
|
|
141
146
|
params[:matcher][:keySelector][:attribute],
|
|
142
|
-
params[:matcher][:whitelistMatcherData][:whitelist]
|
|
147
|
+
params[:matcher][:whitelistMatcherData][:whitelist],
|
|
148
|
+
@config.split_logger
|
|
143
149
|
)
|
|
144
150
|
end
|
|
145
151
|
|
|
146
152
|
def matcher_ends_with(params)
|
|
147
153
|
EndsWithMatcher.new(
|
|
148
154
|
params[:matcher][:keySelector][:attribute],
|
|
149
|
-
params[:matcher][:whitelistMatcherData][:whitelist]
|
|
155
|
+
params[:matcher][:whitelistMatcherData][:whitelist],
|
|
156
|
+
@config.split_logger
|
|
150
157
|
)
|
|
151
158
|
end
|
|
152
159
|
|
|
153
160
|
def matcher_contains_string(params)
|
|
154
161
|
ContainsMatcher.new(
|
|
155
162
|
params[:matcher][:keySelector][:attribute],
|
|
156
|
-
params[:matcher][:whitelistMatcherData][:whitelist]
|
|
163
|
+
params[:matcher][:whitelistMatcherData][:whitelist],
|
|
164
|
+
@config.split_logger, @config.split_validator
|
|
157
165
|
)
|
|
158
166
|
end
|
|
159
167
|
|
|
160
168
|
def matcher_in_split_treatment(params)
|
|
161
169
|
DependencyMatcher.new(
|
|
162
170
|
params[:matcher][:dependencyMatcherData][:split],
|
|
163
|
-
params[:matcher][:dependencyMatcherData][:treatments]
|
|
171
|
+
params[:matcher][:dependencyMatcherData][:treatments],
|
|
172
|
+
@config.split_logger
|
|
164
173
|
)
|
|
165
174
|
end
|
|
166
175
|
|
|
167
176
|
def matcher_equal_to_boolean(params)
|
|
168
177
|
EqualToBooleanMatcher.new(
|
|
169
178
|
params[:matcher][:keySelector][:attribute],
|
|
170
|
-
params[:matcher][:booleanMatcherData]
|
|
179
|
+
params[:matcher][:booleanMatcherData],
|
|
180
|
+
@config.split_logger
|
|
171
181
|
)
|
|
172
182
|
end
|
|
173
183
|
|
|
174
184
|
def matcher_matches_string(params)
|
|
175
185
|
MatchesStringMatcher.new(
|
|
176
186
|
params[:matcher][:keySelector][:attribute],
|
|
177
|
-
params[:matcher][:stringMatcherData]
|
|
187
|
+
params[:matcher][:stringMatcherData],
|
|
188
|
+
@config.split_logger
|
|
178
189
|
)
|
|
179
190
|
end
|
|
180
191
|
|
|
192
|
+
def matcher_equal_to_semver(params)
|
|
193
|
+
EqualToSemverMatcher.new(
|
|
194
|
+
params[:matcher][:keySelector][:attribute],
|
|
195
|
+
params[:matcher][:stringMatcherData],
|
|
196
|
+
@config.split_logger, @config.split_validator
|
|
197
|
+
)
|
|
198
|
+
end
|
|
199
|
+
|
|
200
|
+
def matcher_greater_than_or_equal_to_semver(params)
|
|
201
|
+
GreaterThanOrEqualToSemverMatcher.new(
|
|
202
|
+
params[:matcher][:keySelector][:attribute],
|
|
203
|
+
params[:matcher][:stringMatcherData],
|
|
204
|
+
@config.split_logger, @config.split_validator
|
|
205
|
+
)
|
|
206
|
+
end
|
|
207
|
+
|
|
208
|
+
def matcher_less_than_or_equal_to_semver(params)
|
|
209
|
+
LessThanOrEqualToSemverMatcher.new(
|
|
210
|
+
params[:matcher][:keySelector][:attribute],
|
|
211
|
+
params[:matcher][:stringMatcherData],
|
|
212
|
+
@config.split_logger, @config.split_validator
|
|
213
|
+
)
|
|
214
|
+
end
|
|
215
|
+
|
|
216
|
+
def matcher_between_semver(params)
|
|
217
|
+
BetweenSemverMatcher.new(
|
|
218
|
+
params[:matcher][:keySelector][:attribute],
|
|
219
|
+
params[:matcher][:betweenStringMatcherData][:start],
|
|
220
|
+
params[:matcher][:betweenStringMatcherData][:end],
|
|
221
|
+
@config.split_logger, @config.split_validator
|
|
222
|
+
)
|
|
223
|
+
end
|
|
224
|
+
|
|
225
|
+
def matcher_in_list_semver(params)
|
|
226
|
+
InListSemverMatcher.new(
|
|
227
|
+
params[:matcher][:keySelector][:attribute],
|
|
228
|
+
params[:matcher][:whitelistMatcherData][:whitelist],
|
|
229
|
+
@config.split_logger, @config.split_validator
|
|
230
|
+
)
|
|
231
|
+
end
|
|
232
|
+
|
|
233
|
+
def matcher_in_rule_based_segment(params)
|
|
234
|
+
matcher = params[:matcher]
|
|
235
|
+
segment_name = matcher[:userDefinedSegmentMatcherData] && matcher[:userDefinedSegmentMatcherData][:segmentName]
|
|
236
|
+
|
|
237
|
+
RuleBasedSegmentMatcher.new(params[:segments_repository], params[:rule_based_segments_repository], segment_name, @config)
|
|
238
|
+
end
|
|
239
|
+
|
|
181
240
|
#
|
|
182
241
|
# @return [object] the negate value for this condition
|
|
183
242
|
def negate
|
|
@@ -194,6 +253,8 @@ module SplitIoClient
|
|
|
194
253
|
# @return [void]
|
|
195
254
|
def set_partitions
|
|
196
255
|
partitions_list = []
|
|
256
|
+
return partitions_list unless @data.key?(:partitions) or @data.key?('partitions')
|
|
257
|
+
|
|
197
258
|
@data[:partitions].each do |p|
|
|
198
259
|
partition = SplitIoClient::Partition.new(p)
|
|
199
260
|
partitions_list << partition
|
|
@@ -2,53 +2,52 @@ module SplitIoClient
|
|
|
2
2
|
module Engine
|
|
3
3
|
module Parser
|
|
4
4
|
class Evaluator
|
|
5
|
-
def initialize(segments_repository, splits_repository,
|
|
5
|
+
def initialize(segments_repository, splits_repository, rb_segment_repository, config)
|
|
6
6
|
@splits_repository = splits_repository
|
|
7
7
|
@segments_repository = segments_repository
|
|
8
|
-
@
|
|
9
|
-
@
|
|
8
|
+
@rb_segment_repository = rb_segment_repository
|
|
9
|
+
@config = config
|
|
10
10
|
end
|
|
11
11
|
|
|
12
|
-
def
|
|
12
|
+
def evaluate_feature_flag(keys, feature_flag, attributes = nil)
|
|
13
13
|
# DependencyMatcher here, split is actually a split_name in this case
|
|
14
|
-
cache_result =
|
|
15
|
-
|
|
16
|
-
|
|
14
|
+
cache_result = feature_flag.is_a? String
|
|
15
|
+
feature_flag = @splits_repository.get_split(feature_flag) if cache_result
|
|
16
|
+
evaluate_treatment(keys, feature_flag, attributes)
|
|
17
|
+
end
|
|
17
18
|
|
|
18
|
-
|
|
19
|
-
return treatment_hash(Models::Label::ARCHIVED, Models::Treatment::CONTROL, split[:changeNumber])
|
|
20
|
-
end
|
|
19
|
+
private
|
|
21
20
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
else
|
|
26
|
-
match(split, keys, attributes)
|
|
27
|
-
end
|
|
28
|
-
else
|
|
29
|
-
treatment_hash(Models::Label::KILLED, split[:defaultTreatment], split[:changeNumber], split_configurations(split[:defaultTreatment], split))
|
|
21
|
+
def evaluate_treatment(keys, feature_flag, attributes)
|
|
22
|
+
if Models::Split.archived?(feature_flag)
|
|
23
|
+
return treatment_hash(Models::Label::ARCHIVED, Models::Treatment::CONTROL, feature_flag[:changeNumber])
|
|
30
24
|
end
|
|
31
25
|
|
|
32
|
-
|
|
26
|
+
treatment = if Models::Split.matchable?(feature_flag)
|
|
27
|
+
match(feature_flag, keys, attributes)
|
|
28
|
+
else
|
|
29
|
+
treatment_hash(Models::Label::KILLED, feature_flag[:defaultTreatment], feature_flag[:changeNumber], split_configurations(feature_flag[:defaultTreatment], feature_flag))
|
|
30
|
+
end
|
|
33
31
|
|
|
34
32
|
treatment
|
|
35
33
|
end
|
|
36
34
|
|
|
37
|
-
private
|
|
38
|
-
|
|
39
35
|
def split_configurations(treatment, split)
|
|
40
36
|
return nil if split[:configurations].nil?
|
|
41
37
|
split[:configurations][treatment.to_sym]
|
|
42
38
|
end
|
|
43
39
|
|
|
44
40
|
def match(split, keys, attributes)
|
|
41
|
+
|
|
42
|
+
return treatment_hash(Models::Label::PREREQUISITES_NOT_MET, split[:defaultTreatment], split[:changeNumber], split_configurations(split[:defaultTreatment], split)) unless check_prerequisites_matcher(split, keys, attributes)
|
|
43
|
+
|
|
45
44
|
in_rollout = false
|
|
46
45
|
key = keys[:bucketing_key] ? keys[:bucketing_key] : keys[:matching_key]
|
|
47
46
|
legacy_algo = (split[:algo] == 1 || split[:algo] == nil) ? true : false
|
|
48
47
|
splitter = Splitter.new
|
|
49
48
|
|
|
50
49
|
split[:conditions].each do |c|
|
|
51
|
-
condition = SplitIoClient::Condition.new(c)
|
|
50
|
+
condition = SplitIoClient::Condition.new(c, @config)
|
|
52
51
|
|
|
53
52
|
next if condition.empty?
|
|
54
53
|
|
|
@@ -63,8 +62,7 @@ module SplitIoClient
|
|
|
63
62
|
|
|
64
63
|
in_rollout = true
|
|
65
64
|
end
|
|
66
|
-
|
|
67
|
-
condition_matched = matcher_type(condition).match?(
|
|
65
|
+
condition_matched = Helpers::EvaluatorHelper::matcher_type(condition, @segments_repository, @rb_segment_repository).match?(
|
|
68
66
|
matching_key: keys[:matching_key],
|
|
69
67
|
bucketing_key: keys[:bucketing_key],
|
|
70
68
|
evaluator: self,
|
|
@@ -75,35 +73,19 @@ module SplitIoClient
|
|
|
75
73
|
|
|
76
74
|
result = splitter.get_treatment(key, split[:seed], condition.partitions, split[:algo])
|
|
77
75
|
|
|
78
|
-
|
|
79
|
-
return treatment_hash(Models::Label::NO_RULE_MATCHED, split[:defaultTreatment], split[:changeNumber], split_configurations(split[:defaultTreatment], split))
|
|
80
|
-
else
|
|
81
|
-
return treatment_hash(c[:label], result, split[:changeNumber],split_configurations(result, split))
|
|
82
|
-
end
|
|
76
|
+
return treatment_from_result(result, split, c)
|
|
83
77
|
end
|
|
84
78
|
|
|
85
79
|
treatment_hash(Models::Label::NO_RULE_MATCHED, split[:defaultTreatment], split[:changeNumber], split_configurations(split[:defaultTreatment], split))
|
|
86
80
|
end
|
|
87
81
|
|
|
88
|
-
|
|
89
|
-
matchers = []
|
|
90
|
-
|
|
91
|
-
@segments_repository.adapter.pipelined do
|
|
92
|
-
condition.matchers.each do |matcher|
|
|
93
|
-
matchers << if matcher[:negate]
|
|
94
|
-
condition.negation_matcher(matcher_instance(matcher[:matcherType], condition, matcher))
|
|
95
|
-
else
|
|
96
|
-
matcher_instance(matcher[:matcherType], condition, matcher)
|
|
97
|
-
end
|
|
98
|
-
end
|
|
99
|
-
end
|
|
100
|
-
|
|
101
|
-
final_matcher = condition.create_condition_matcher(matchers)
|
|
82
|
+
private
|
|
102
83
|
|
|
103
|
-
|
|
104
|
-
|
|
84
|
+
def treatment_from_result(result, split, condition)
|
|
85
|
+
if result.nil?
|
|
86
|
+
return treatment_hash(Models::Label::NO_RULE_MATCHED, split[:defaultTreatment], split[:changeNumber], split_configurations(split[:defaultTreatment], split))
|
|
105
87
|
else
|
|
106
|
-
|
|
88
|
+
return treatment_hash(condition[:label], result, split[:changeNumber],split_configurations(result, split))
|
|
107
89
|
end
|
|
108
90
|
end
|
|
109
91
|
|
|
@@ -111,11 +93,18 @@ module SplitIoClient
|
|
|
111
93
|
{ label: label, treatment: treatment, change_number: change_number, config: configurations }
|
|
112
94
|
end
|
|
113
95
|
|
|
114
|
-
def
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
96
|
+
def check_prerequisites_matcher(split, keys, attributes)
|
|
97
|
+
if split.key?(:prerequisites) && !split[:prerequisites].nil?
|
|
98
|
+
prerequisites_matcher = SplitIoClient::PrerequisitesMatcher.new(split[:prerequisites], @config.split_logger)
|
|
99
|
+
return prerequisites_matcher.match?(
|
|
100
|
+
matching_key: keys[:matching_key],
|
|
101
|
+
bucketing_key: keys[:bucketing_key],
|
|
102
|
+
evaluator: self,
|
|
103
|
+
attributes: attributes
|
|
104
|
+
)
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
true
|
|
119
108
|
end
|
|
120
109
|
end
|
|
121
110
|
end
|