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
|
@@ -1,126 +1,198 @@
|
|
|
1
1
|
module SplitIoClient
|
|
2
|
+
EVENTS_SIZE_THRESHOLD = 32768
|
|
3
|
+
EVENT_AVERAGE_SIZE = 1024
|
|
4
|
+
GET_TREATMENT = 'get_treatment'
|
|
5
|
+
GET_TREATMENTS = 'get_treatments'
|
|
6
|
+
GET_TREATMENT_WITH_CONFIG = 'get_treatment_with_config'
|
|
7
|
+
GET_TREATMENTS_WITH_CONFIG = 'get_treatments_with_config'
|
|
8
|
+
GET_TREATMENTS_BY_FLAG_SET = 'get_treatments_by_flag_set'
|
|
9
|
+
GET_TREATMENTS_BY_FLAG_SETS = 'get_treatments_by_flag_sets'
|
|
10
|
+
GET_TREATMENTS_WITH_CONFIG_BY_FLAG_SET = 'get_treatments_with_config_by_flag_set'
|
|
11
|
+
GET_TREATMENTS_WITH_CONFIG_BY_FLAG_SETS = 'get_treatments_with_config_by_flag_sets'
|
|
12
|
+
TRACK = 'track'
|
|
2
13
|
|
|
3
14
|
class SplitClient
|
|
4
15
|
#
|
|
5
16
|
# Creates a new split client instance that connects to split.io API.
|
|
6
17
|
#
|
|
7
|
-
# @param
|
|
18
|
+
# @param sdk_key [String] the SDK key for your split account
|
|
8
19
|
#
|
|
9
20
|
# @return [SplitIoClient] split.io client instance
|
|
10
|
-
def initialize(
|
|
11
|
-
@
|
|
12
|
-
@
|
|
13
|
-
@
|
|
14
|
-
@
|
|
15
|
-
@
|
|
21
|
+
def initialize(sdk_key, repositories, status_manager, config, impressions_manager, telemetry_evaluation_producer, evaluator, split_validator, fallback_treatment_calculator, events_manager)
|
|
22
|
+
@api_key = sdk_key
|
|
23
|
+
@splits_repository = repositories[:splits]
|
|
24
|
+
@segments_repository = repositories[:segments]
|
|
25
|
+
@rule_based_segments_repository = repositories[:rule_based_segments]
|
|
26
|
+
@impressions_repository = repositories[:impressions]
|
|
27
|
+
@events_repository = repositories[:events]
|
|
28
|
+
@status_manager = status_manager
|
|
16
29
|
@destroyed = false
|
|
17
|
-
|
|
18
|
-
@
|
|
30
|
+
@config = config
|
|
31
|
+
@impressions_manager = impressions_manager
|
|
32
|
+
@telemetry_evaluation_producer = telemetry_evaluation_producer
|
|
33
|
+
@split_validator = split_validator
|
|
34
|
+
@evaluator = evaluator
|
|
35
|
+
@fallback_treatment_calculator = fallback_treatment_calculator
|
|
36
|
+
@events_manager = events_manager
|
|
19
37
|
end
|
|
20
38
|
|
|
21
39
|
def get_treatment(
|
|
22
|
-
key, split_name, attributes = {}, split_data = nil, store_impressions =
|
|
40
|
+
key, split_name, attributes = {}, evaluation_options = nil, split_data = nil, store_impressions = nil,
|
|
23
41
|
multiple = false, evaluator = nil
|
|
24
42
|
)
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
end
|
|
43
|
+
log_deprecated_warning(GET_TREATMENT, evaluator, 'evaluator')
|
|
44
|
+
|
|
45
|
+
result = treatment(key, split_name, attributes, split_data, store_impressions, GET_TREATMENT, multiple, evaluation_options)
|
|
46
|
+
return result.tap { |t| t.delete(:config) } if multiple
|
|
47
|
+
result[:treatment]
|
|
31
48
|
end
|
|
32
49
|
|
|
33
50
|
def get_treatment_with_config(
|
|
34
|
-
key, split_name, attributes = {}, split_data = nil, store_impressions =
|
|
51
|
+
key, split_name, attributes = {}, evaluation_options = nil, split_data = nil, store_impressions = nil,
|
|
35
52
|
multiple = false, evaluator = nil
|
|
36
53
|
)
|
|
37
|
-
|
|
54
|
+
log_deprecated_warning(GET_TREATMENT, evaluator, 'evaluator')
|
|
55
|
+
result = treatment(key, split_name, attributes, split_data, store_impressions, GET_TREATMENT_WITH_CONFIG, multiple, evaluation_options)
|
|
56
|
+
|
|
57
|
+
{ :config => result[:config], :treatment => result[:treatment] }
|
|
38
58
|
end
|
|
39
59
|
|
|
40
|
-
def get_treatments(key, split_names, attributes = {})
|
|
41
|
-
treatments = treatments(key, split_names, attributes)
|
|
60
|
+
def get_treatments(key, split_names, attributes = {}, evaluation_options = nil)
|
|
61
|
+
treatments = treatments(key, split_names, attributes, evaluation_options)
|
|
62
|
+
|
|
42
63
|
return treatments if treatments.nil?
|
|
43
64
|
keys = treatments.keys
|
|
44
65
|
treats = treatments.map { |_,t| t[:treatment] }
|
|
45
66
|
Hash[keys.zip(treats)]
|
|
46
67
|
end
|
|
47
68
|
|
|
48
|
-
def get_treatments_with_config(key, split_names, attributes = {})
|
|
49
|
-
treatments(key, split_names, attributes,
|
|
69
|
+
def get_treatments_with_config(key, split_names, attributes = {}, evaluation_options = nil)
|
|
70
|
+
results = treatments(key, split_names, attributes, evaluation_options, GET_TREATMENTS_WITH_CONFIG)
|
|
71
|
+
|
|
72
|
+
results.map{|key, value|
|
|
73
|
+
[key, { treatment: value[:treatment], config: value[:config] }]
|
|
74
|
+
}.to_h
|
|
50
75
|
end
|
|
51
76
|
|
|
52
|
-
def
|
|
53
|
-
|
|
77
|
+
def get_treatments_by_flag_set(key, flag_set, attributes = {}, evaluation_options = nil)
|
|
78
|
+
valid_flag_set = @split_validator.valid_flag_sets(GET_TREATMENTS_BY_FLAG_SET, [flag_set])
|
|
79
|
+
split_names = @splits_repository.get_feature_flags_by_sets(valid_flag_set)
|
|
80
|
+
treatments = treatments(key, split_names, attributes, evaluation_options, GET_TREATMENTS_BY_FLAG_SET)
|
|
81
|
+
return treatments if treatments.nil?
|
|
82
|
+
keys = treatments.keys
|
|
83
|
+
treats = treatments.map { |_,t| t[:treatment] }
|
|
84
|
+
Hash[keys.zip(treats)]
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
def get_treatments_by_flag_sets(key, flag_sets, attributes = {}, evaluation_options = nil)
|
|
88
|
+
valid_flag_set = @split_validator.valid_flag_sets(GET_TREATMENTS_BY_FLAG_SETS, flag_sets)
|
|
89
|
+
split_names = @splits_repository.get_feature_flags_by_sets(valid_flag_set)
|
|
90
|
+
treatments = treatments(key, split_names, attributes, evaluation_options, GET_TREATMENTS_BY_FLAG_SETS)
|
|
91
|
+
return treatments if treatments.nil?
|
|
92
|
+
keys = treatments.keys
|
|
93
|
+
treats = treatments.map { |_,t| t[:treatment] }
|
|
94
|
+
Hash[keys.zip(treats)]
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
def get_treatments_with_config_by_flag_set(key, flag_set, attributes = {}, evaluation_options = nil)
|
|
98
|
+
valid_flag_set = @split_validator.valid_flag_sets(GET_TREATMENTS_WITH_CONFIG_BY_FLAG_SET, [flag_set])
|
|
99
|
+
split_names = @splits_repository.get_feature_flags_by_sets(valid_flag_set)
|
|
100
|
+
results = treatments(key, split_names, attributes, evaluation_options, GET_TREATMENTS_WITH_CONFIG_BY_FLAG_SET)
|
|
101
|
+
|
|
102
|
+
results.map{|key, value|
|
|
103
|
+
[key, { treatment: value[:treatment], config: value[:config] }]
|
|
104
|
+
}.to_h
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
def get_treatments_with_config_by_flag_sets(key, flag_sets, attributes = {}, evaluation_options = nil)
|
|
108
|
+
valid_flag_set = @split_validator.valid_flag_sets(GET_TREATMENTS_WITH_CONFIG_BY_FLAG_SETS, flag_sets)
|
|
109
|
+
split_names = @splits_repository.get_feature_flags_by_sets(valid_flag_set)
|
|
110
|
+
results = treatments(key, split_names, attributes, evaluation_options, GET_TREATMENTS_WITH_CONFIG_BY_FLAG_SETS)
|
|
111
|
+
|
|
112
|
+
results.map{|key, value|
|
|
113
|
+
[key, { treatment: value[:treatment], config: value[:config] }]
|
|
114
|
+
}.to_h
|
|
115
|
+
end
|
|
54
116
|
|
|
55
|
-
|
|
117
|
+
def destroy
|
|
118
|
+
@config.logger.info('Split client shutdown started...') if @config.debug_enabled
|
|
119
|
+
if !@config.cache_adapter.is_a?(SplitIoClient::Cache::Adapters::RedisAdapter) && @config.impressions_mode != :none &&
|
|
120
|
+
(!@impressions_repository.empty? || !@events_repository.empty?)
|
|
121
|
+
@config.logger.debug("Impressions and/or Events cache is not empty") if @config.debug_enabled
|
|
122
|
+
# Adding small delay to ensure sender threads are fully running
|
|
123
|
+
sleep(0.1)
|
|
124
|
+
if !@config.threads.key?(:impressions_sender) || !@config.threads.key?(:events_sender)
|
|
125
|
+
@config.logger.debug("Periodic data recording thread has not started yet, waiting for service startup.") if @config.debug_enabled
|
|
126
|
+
@config.threads[:start_sdk].join(5) if @config.threads.key?(:start_sdk)
|
|
127
|
+
end
|
|
128
|
+
end
|
|
129
|
+
@config.threads.select { |name, thread| name.to_s.end_with? 'sender' }.values.each do |thread|
|
|
56
130
|
thread.raise(SplitIoClient::SDKShutdownException)
|
|
57
131
|
thread.join
|
|
58
132
|
end
|
|
59
133
|
|
|
60
|
-
|
|
134
|
+
@config.threads.values.each { |thread| Thread.kill(thread) }
|
|
61
135
|
|
|
62
136
|
@splits_repository.clear
|
|
63
137
|
@segments_repository.clear
|
|
138
|
+
@rule_based_segments_repository.clear
|
|
139
|
+
|
|
140
|
+
SplitIoClient.load_factory_registry
|
|
141
|
+
SplitIoClient.split_factory_registry.remove(@api_key)
|
|
64
142
|
|
|
65
|
-
|
|
66
|
-
|
|
143
|
+
@config.logger.info('Split client shutdown complete') if @config.debug_enabled
|
|
144
|
+
@config.valid_mode = false
|
|
67
145
|
@destroyed = true
|
|
68
146
|
end
|
|
69
147
|
|
|
70
|
-
def
|
|
71
|
-
|
|
148
|
+
def track(key, traffic_type_name, event_type, value = nil, properties = nil)
|
|
149
|
+
return false unless valid_client && @config.split_validator.valid_track_parameters(key, traffic_type_name, event_type, value, properties)
|
|
150
|
+
|
|
151
|
+
start = Time.now
|
|
152
|
+
properties_size = EVENT_AVERAGE_SIZE
|
|
72
153
|
|
|
73
|
-
|
|
154
|
+
if !properties.nil?
|
|
155
|
+
properties, size = validate_properties(properties)
|
|
156
|
+
properties_size += size
|
|
157
|
+
return false unless check_properties_size(properties_size)
|
|
158
|
+
end
|
|
74
159
|
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
time
|
|
81
|
-
)
|
|
160
|
+
if ready? && !@config.localhost_mode && !@splits_repository.traffic_type_exists(traffic_type_name)
|
|
161
|
+
@config.logger.warn("track: Traffic Type #{traffic_type_name} " \
|
|
162
|
+
"does not have any corresponding feature flags in this environment, make sure you're tracking " \
|
|
163
|
+
'your events to a valid traffic type defined in the Split user interface')
|
|
164
|
+
end
|
|
82
165
|
|
|
83
|
-
|
|
166
|
+
@events_repository.add(key.to_s, traffic_type_name.downcase, event_type.to_s, (Time.now.to_f * 1000).to_i, value, properties, properties_size)
|
|
167
|
+
record_latency(TRACK, start)
|
|
168
|
+
true
|
|
169
|
+
rescue StandardError => e
|
|
170
|
+
@config.log_found_exception(__method__.to_s, e)
|
|
171
|
+
record_exception(TRACK)
|
|
84
172
|
|
|
85
|
-
|
|
86
|
-
SplitIoClient.configuration.log_found_exception(__method__.to_s, error)
|
|
173
|
+
false
|
|
87
174
|
end
|
|
88
175
|
|
|
89
|
-
def
|
|
90
|
-
|
|
91
|
-
split_name: split_name,
|
|
92
|
-
matching_key: matching_key,
|
|
93
|
-
bucketing_key: bucketing_key,
|
|
94
|
-
time: time,
|
|
95
|
-
treatment: treatment,
|
|
96
|
-
attributes: attributes
|
|
97
|
-
)
|
|
176
|
+
def block_until_ready(time = nil)
|
|
177
|
+
@status_manager.wait_until_ready(time) if @status_manager
|
|
98
178
|
end
|
|
99
179
|
|
|
100
|
-
def
|
|
101
|
-
|
|
102
|
-
split_names: split_names,
|
|
103
|
-
matching_key: matching_key,
|
|
104
|
-
bucketing_key: bucketing_key,
|
|
105
|
-
time: time,
|
|
106
|
-
treatments_labels_change_numbers: treatments_labels_change_numbers,
|
|
107
|
-
attributes: attributes
|
|
108
|
-
)
|
|
180
|
+
def register(sdk_event, handler)
|
|
181
|
+
@events_manager.register(sdk_event, handler)
|
|
109
182
|
end
|
|
110
183
|
|
|
111
|
-
def
|
|
112
|
-
@
|
|
184
|
+
def unregister(sdk_event, handler)
|
|
185
|
+
@events_manager.unregister(sdk_event)
|
|
113
186
|
end
|
|
114
187
|
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
SplitIoClient.configuration.log_found_exception(__method__.to_s, error)
|
|
122
|
-
false
|
|
188
|
+
private
|
|
189
|
+
|
|
190
|
+
def check_properties_size(properties_size, msg = "Event not queued")
|
|
191
|
+
if (properties_size > EVENTS_SIZE_THRESHOLD)
|
|
192
|
+
@config.logger.error("The maximum size allowed for the properties is #{EVENTS_SIZE_THRESHOLD}. Current is #{properties_size}. #{msg}")
|
|
193
|
+
return false
|
|
123
194
|
end
|
|
195
|
+
return true
|
|
124
196
|
end
|
|
125
197
|
|
|
126
198
|
def keys_from_key(key)
|
|
@@ -132,7 +204,7 @@ module SplitIoClient
|
|
|
132
204
|
end
|
|
133
205
|
end
|
|
134
206
|
|
|
135
|
-
def parsed_treatment(
|
|
207
|
+
def parsed_treatment(treatment_data, multiple = false)
|
|
136
208
|
if multiple
|
|
137
209
|
{
|
|
138
210
|
treatment: treatment_data[:treatment],
|
|
@@ -141,78 +213,141 @@ module SplitIoClient
|
|
|
141
213
|
config: treatment_data[:config]
|
|
142
214
|
}
|
|
143
215
|
else
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
216
|
+
{
|
|
217
|
+
treatment: treatment_data[:treatment],
|
|
218
|
+
config: treatment_data[:config],
|
|
219
|
+
}
|
|
148
220
|
end
|
|
149
221
|
end
|
|
150
222
|
|
|
151
223
|
def sanitize_split_names(calling_method, split_names)
|
|
224
|
+
return nil if !split_names.is_a?(Array)
|
|
225
|
+
|
|
152
226
|
split_names.compact.uniq.select do |split_name|
|
|
153
|
-
if
|
|
227
|
+
if split_name.nil?
|
|
228
|
+
false
|
|
229
|
+
elsif (split_name.is_a?(String) || split_name.is_a?(Symbol)) && !split_name.empty?
|
|
154
230
|
true
|
|
155
231
|
elsif split_name.is_a?(String) && split_name.empty?
|
|
156
|
-
|
|
232
|
+
@config.logger.warn("#{calling_method}: you passed an empty feature_flag_name, flag name must be a non-empty String or a Symbol")
|
|
157
233
|
false
|
|
158
234
|
else
|
|
159
|
-
|
|
235
|
+
@config.logger.warn("#{calling_method}: you passed an invalid feature_flag_name, flag name must be a non-empty String or a Symbol")
|
|
160
236
|
false
|
|
161
237
|
end
|
|
162
238
|
end
|
|
163
239
|
end
|
|
164
240
|
|
|
165
|
-
|
|
241
|
+
def validate_properties(properties, method = 'Event')
|
|
242
|
+
properties_count = 0
|
|
243
|
+
size = 0
|
|
244
|
+
|
|
245
|
+
fixed_properties = properties.each_with_object({}) { |(key, value), result|
|
|
246
|
+
|
|
247
|
+
if(key.is_a?(String) || key.is_a?(Symbol))
|
|
248
|
+
properties_count += 1
|
|
249
|
+
size += variable_size(key)
|
|
250
|
+
if value.is_a?(String) || value.is_a?(Symbol) || value.is_a?(Numeric) || value.is_a?(TrueClass) || value.is_a?(FalseClass) || value.nil?
|
|
251
|
+
result[key] = value
|
|
252
|
+
size += variable_size(value)
|
|
253
|
+
else
|
|
254
|
+
@config.logger.warn("Property #{key} is of invalid type. Setting value to nil")
|
|
255
|
+
result[key] = nil
|
|
256
|
+
end
|
|
257
|
+
end
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
@config.logger.warn("#{method} has more than 300 properties. Some of them will be trimmed when processed") if properties_count > 300
|
|
261
|
+
|
|
262
|
+
return fixed_properties, size
|
|
263
|
+
end
|
|
264
|
+
|
|
265
|
+
def validate_evaluation_options(evaluation_options)
|
|
266
|
+
if !evaluation_options.is_a?(SplitIoClient::Engine::Models::EvaluationOptions)
|
|
267
|
+
@config.logger.warn("Option #{evaluation_options} should be a EvaluationOptions type. Setting value to nil")
|
|
268
|
+
return nil, 0
|
|
269
|
+
end
|
|
270
|
+
evaluation_options.properties = evaluation_options.properties.transform_keys(&:to_sym)
|
|
271
|
+
evaluation_options.properties, size = validate_properties(evaluation_options.properties, 'Treatment')
|
|
272
|
+
return evaluation_options, size
|
|
273
|
+
end
|
|
166
274
|
|
|
167
275
|
def valid_client
|
|
168
276
|
if @destroyed
|
|
169
|
-
|
|
277
|
+
@config.logger.error('Client has already been destroyed - no calls possible')
|
|
170
278
|
return false
|
|
171
279
|
end
|
|
172
|
-
|
|
280
|
+
@config.valid_mode
|
|
173
281
|
end
|
|
174
282
|
|
|
175
|
-
def treatments(key,
|
|
176
|
-
|
|
283
|
+
def treatments(key, feature_flag_names, attributes = {}, evaluation_options = nil, calling_method = 'get_treatments')
|
|
284
|
+
sanitized_feature_flag_names = sanitize_split_names(calling_method, feature_flag_names)
|
|
177
285
|
|
|
178
|
-
|
|
286
|
+
if sanitized_feature_flag_names.nil?
|
|
287
|
+
@config.logger.error("#{calling_method}: feature_flag_names must be a non-empty Array")
|
|
288
|
+
return nil
|
|
289
|
+
end
|
|
179
290
|
|
|
180
|
-
if
|
|
181
|
-
|
|
291
|
+
if sanitized_feature_flag_names.empty?
|
|
292
|
+
@config.logger.error("#{calling_method}: feature_flag_names must be a non-empty Array")
|
|
182
293
|
return {}
|
|
183
294
|
end
|
|
184
295
|
|
|
185
296
|
bucketing_key, matching_key = keys_from_key(key)
|
|
186
297
|
bucketing_key = bucketing_key ? bucketing_key.to_s : nil
|
|
187
298
|
matching_key = matching_key ? matching_key.to_s : nil
|
|
299
|
+
attributes = parsed_attributes(attributes)
|
|
188
300
|
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
# Measure
|
|
197
|
-
@adapter.metrics.time('sdk.' + calling_method, latency)
|
|
301
|
+
if !@config.split_validator.valid_get_treatments_parameters(calling_method, key, sanitized_feature_flag_names, matching_key, bucketing_key, attributes)
|
|
302
|
+
to_return = Hash.new
|
|
303
|
+
sanitized_feature_flag_names.each {|name|
|
|
304
|
+
to_return[name.to_sym] = check_fallback_treatment(name, '')
|
|
305
|
+
}
|
|
306
|
+
return to_return
|
|
307
|
+
end
|
|
198
308
|
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
309
|
+
if !ready?
|
|
310
|
+
impressions = []
|
|
311
|
+
to_return = Hash.new
|
|
312
|
+
sanitized_feature_flag_names.each {|name|
|
|
313
|
+
treatment_data = check_fallback_treatment(name, Engine::Models::Label::NOT_READY)
|
|
314
|
+
to_return[name.to_sym] = treatment_data
|
|
204
315
|
|
|
205
|
-
|
|
316
|
+
impressions << { :impression => @impressions_manager.build_impression(matching_key, bucketing_key, name.to_sym,
|
|
317
|
+
get_treatment_without_config(treatment_data), false, { attributes: attributes, time: nil },
|
|
318
|
+
evaluation_options), :disabled => false }
|
|
319
|
+
}
|
|
320
|
+
@impressions_manager.track(impressions)
|
|
321
|
+
return to_return
|
|
206
322
|
end
|
|
207
323
|
|
|
208
|
-
|
|
209
|
-
|
|
324
|
+
valid_feature_flag_names = []
|
|
325
|
+
sanitized_feature_flag_names.each { |feature_flag_name|
|
|
326
|
+
valid_feature_flag_names << feature_flag_name unless feature_flag_name.nil?
|
|
327
|
+
}
|
|
328
|
+
start = Time.now
|
|
329
|
+
|
|
330
|
+
feature_flags = @splits_repository.splits(valid_feature_flag_names)
|
|
331
|
+
treatments = Hash.new
|
|
332
|
+
invalid_treatments = Hash.new
|
|
333
|
+
feature_flags.each do |key, feature_flag|
|
|
334
|
+
if feature_flag.nil?
|
|
335
|
+
@config.logger.warn("#{calling_method}: you passed #{key} that " \
|
|
336
|
+
'does not exist in this environment, please double check what feature flags exist in the Split user interface')
|
|
337
|
+
invalid_treatments[key] = check_fallback_treatment(key, Engine::Models::Label::NOT_FOUND)
|
|
338
|
+
next
|
|
339
|
+
end
|
|
340
|
+
treatments_labels_change_numbers, impressions = evaluate_treatment(feature_flag, key, bucketing_key, matching_key, attributes, calling_method, false, evaluation_options)
|
|
341
|
+
treatments[key] =
|
|
210
342
|
{
|
|
211
|
-
treatment:
|
|
212
|
-
config:
|
|
343
|
+
treatment: treatments_labels_change_numbers[:treatment],
|
|
344
|
+
config: treatments_labels_change_numbers[:config]
|
|
213
345
|
}
|
|
346
|
+
@impressions_manager.track(impressions) unless impressions.empty?
|
|
214
347
|
end
|
|
215
|
-
|
|
348
|
+
record_latency(calling_method, start)
|
|
349
|
+
|
|
350
|
+
treatments.merge(invalid_treatments)
|
|
216
351
|
end
|
|
217
352
|
|
|
218
353
|
#
|
|
@@ -223,61 +358,173 @@ module SplitIoClient
|
|
|
223
358
|
# @param attributes [Hash] attributes to pass to the treatment class
|
|
224
359
|
# @param split_data [Hash] split data, when provided this method doesn't fetch splits_repository for the data
|
|
225
360
|
# @param store_impressions [Boolean] impressions aren't stored if this flag is false
|
|
226
|
-
# @param multiple [Hash] internal flag to signal if method is called by get_treatments
|
|
227
|
-
# @param evaluator [Evaluator] Evaluator class instance, used to cache treatments
|
|
228
|
-
#
|
|
229
361
|
# @return [String/Hash] Treatment as String or Hash of treatments in case of array of features
|
|
230
|
-
def treatment(
|
|
231
|
-
|
|
232
|
-
multiple = false, evaluator = nil, calling_method = 'get_treatment'
|
|
233
|
-
)
|
|
234
|
-
control_treatment = { label: Engine::Models::Label::EXCEPTION, treatment: SplitIoClient::Engine::Models::Treatment::CONTROL, config: nil }
|
|
235
|
-
parsed_control_treatment = parsed_treatment(multiple, control_treatment)
|
|
362
|
+
def treatment(key, feature_flag_name, attributes = {}, split_data = nil, store_impressions = nil,
|
|
363
|
+
calling_method = 'get_treatment', multiple = false, evaluation_options = nil)
|
|
236
364
|
|
|
365
|
+
log_deprecated_warning(calling_method, split_data, 'split_data')
|
|
366
|
+
log_deprecated_warning(calling_method, store_impressions, 'store_impressions')
|
|
367
|
+
|
|
368
|
+
impressions = []
|
|
237
369
|
bucketing_key, matching_key = keys_from_key(key)
|
|
238
370
|
|
|
239
|
-
|
|
371
|
+
attributes = parsed_attributes(attributes)
|
|
372
|
+
|
|
373
|
+
return parsed_treatment(check_fallback_treatment(feature_flag_name, ""), multiple) unless valid_client && @config.split_validator.valid_get_treatment_parameters(calling_method, key, feature_flag_name, matching_key, bucketing_key, attributes)
|
|
240
374
|
|
|
241
375
|
bucketing_key = bucketing_key ? bucketing_key.to_s : nil
|
|
242
376
|
matching_key = matching_key.to_s
|
|
243
|
-
|
|
377
|
+
sanitized_feature_flag_name = feature_flag_name.to_s.strip
|
|
244
378
|
|
|
245
|
-
if
|
|
246
|
-
|
|
247
|
-
|
|
379
|
+
if feature_flag_name.to_s != sanitized_feature_flag_name
|
|
380
|
+
@config.logger.warn("#{calling_method}: feature_flag_name #{feature_flag_name} has extra whitespace, trimming")
|
|
381
|
+
feature_flag_name = sanitized_feature_flag_name
|
|
248
382
|
end
|
|
249
383
|
|
|
250
|
-
|
|
384
|
+
feature_flag = @splits_repository.get_split(feature_flag_name)
|
|
385
|
+
treatments, impressions_decorator = evaluate_treatment(feature_flag, feature_flag_name, bucketing_key, matching_key, attributes, calling_method, multiple, evaluation_options)
|
|
386
|
+
|
|
387
|
+
@impressions_manager.track(impressions_decorator) unless impressions_decorator.nil?
|
|
388
|
+
treatments
|
|
389
|
+
end
|
|
390
|
+
|
|
391
|
+
def log_deprecated_warning(calling_method, parameter, parameter_name)
|
|
392
|
+
@config.logger.warn("#{calling_method}: detected #{parameter_name} parameter used, this parameter is deprecated and its value is ignored.") unless parameter.nil?
|
|
393
|
+
end
|
|
251
394
|
|
|
395
|
+
def evaluate_treatment(feature_flag, feature_flag_name, bucketing_key, matching_key, attributes, calling_method, multiple = false, evaluation_options = nil)
|
|
396
|
+
impressions_decorator = []
|
|
252
397
|
begin
|
|
253
398
|
start = Time.now
|
|
399
|
+
if feature_flag.nil? && ready?
|
|
400
|
+
@config.logger.warn("#{calling_method}: you passed #{feature_flag_name} that " \
|
|
401
|
+
'does not exist in this environment, please double check what feature flags exist in the Split user interface')
|
|
402
|
+
return check_fallback_treatment(feature_flag_name, Engine::Models::Label::NOT_FOUND), nil
|
|
403
|
+
end
|
|
254
404
|
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
405
|
+
if !feature_flag.nil? && ready?
|
|
406
|
+
treatment_data = @evaluator.evaluate_feature_flag(
|
|
407
|
+
{ bucketing_key: bucketing_key, matching_key: matching_key }, feature_flag, attributes
|
|
408
|
+
)
|
|
409
|
+
impressions_disabled = feature_flag[:impressionsDisabled]
|
|
410
|
+
else
|
|
411
|
+
@config.logger.error("#{calling_method}: the SDK is not ready, results may be incorrect for feature flag #{feature_flag_name}. Make sure to wait for SDK readiness before using this method.")
|
|
412
|
+
treatment_data = check_fallback_treatment(feature_flag_name, Engine::Models::Label::NOT_READY)
|
|
413
|
+
impressions_disabled = false
|
|
260
414
|
end
|
|
261
415
|
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
)
|
|
416
|
+
evaluation_options, size = validate_evaluation_options(evaluation_options) unless evaluation_options.nil?
|
|
417
|
+
evaluation_options.properties = nil unless evaluation_options.nil? or check_properties_size((EVENT_AVERAGE_SIZE + size), "Properties are ignored")
|
|
418
|
+
|
|
419
|
+
record_latency(calling_method, start)
|
|
420
|
+
impression_decorator = { :impression => @impressions_manager.build_impression(matching_key, bucketing_key, feature_flag_name, treatment_data, impressions_disabled, { attributes: attributes, time: nil }, evaluation_options), :disabled => impressions_disabled }
|
|
421
|
+
impressions_decorator << impression_decorator unless impression_decorator.nil?
|
|
422
|
+
rescue StandardError => e
|
|
423
|
+
@config.log_found_exception(__method__.to_s, e)
|
|
424
|
+
record_exception(calling_method)
|
|
425
|
+
treatment_data = check_fallback_treatment(feature_flag_name, Engine::Models::Label::EXCEPTION)
|
|
426
|
+
impression_decorator = { :impression => @impressions_manager.build_impression(matching_key, bucketing_key, feature_flag_name, get_treatment_without_config(treatment_data), false, { attributes: attributes, time: nil }, evaluation_options), :disabled => false }
|
|
427
|
+
|
|
428
|
+
impressions_decorator << impression_decorator unless impression_decorator.nil?
|
|
429
|
+
|
|
430
|
+
return parsed_treatment(treatment_data, multiple), impressions_decorator
|
|
431
|
+
end
|
|
432
|
+
return parsed_treatment(treatment_data, multiple), impressions_decorator
|
|
433
|
+
end
|
|
434
|
+
|
|
435
|
+
def variable_size(value)
|
|
436
|
+
value.is_a?(String) ? value.length : 0
|
|
437
|
+
end
|
|
438
|
+
|
|
439
|
+
def ready?
|
|
440
|
+
return @status_manager.ready? if @status_manager
|
|
441
|
+
true
|
|
442
|
+
end
|
|
443
|
+
|
|
444
|
+
def parsed_attributes(attributes)
|
|
445
|
+
return attributes || attributes.to_h
|
|
446
|
+
end
|
|
447
|
+
|
|
448
|
+
def record_latency(method, start)
|
|
449
|
+
bucket = BinarySearchLatencyTracker.get_bucket((Time.now - start) * 1000.0)
|
|
450
|
+
|
|
451
|
+
case method
|
|
452
|
+
when GET_TREATMENT
|
|
453
|
+
@telemetry_evaluation_producer.record_latency(Telemetry::Domain::Constants::TREATMENT, bucket)
|
|
454
|
+
when GET_TREATMENTS
|
|
455
|
+
@telemetry_evaluation_producer.record_latency(Telemetry::Domain::Constants::TREATMENTS, bucket)
|
|
456
|
+
when GET_TREATMENT_WITH_CONFIG
|
|
457
|
+
@telemetry_evaluation_producer.record_latency(Telemetry::Domain::Constants::TREATMENT_WITH_CONFIG, bucket)
|
|
458
|
+
when GET_TREATMENTS_WITH_CONFIG
|
|
459
|
+
@telemetry_evaluation_producer.record_latency(Telemetry::Domain::Constants::TREATMENTS_WITH_CONFIG, bucket)
|
|
460
|
+
when GET_TREATMENTS_BY_FLAG_SET
|
|
461
|
+
@telemetry_evaluation_producer.record_latency(Telemetry::Domain::Constants::TREATMENTS_BY_FLAG_SET, bucket)
|
|
462
|
+
when GET_TREATMENTS_BY_FLAG_SETS
|
|
463
|
+
@telemetry_evaluation_producer.record_latency(Telemetry::Domain::Constants::TREATMENTS_BY_FLAG_SETS, bucket)
|
|
464
|
+
when GET_TREATMENTS_WITH_CONFIG_BY_FLAG_SET
|
|
465
|
+
@telemetry_evaluation_producer.record_latency(Telemetry::Domain::Constants::TREATMENTS_WITH_CONFIG_BY_FLAG_SET, bucket)
|
|
466
|
+
when GET_TREATMENTS_WITH_CONFIG_BY_FLAG_SETS
|
|
467
|
+
@telemetry_evaluation_producer.record_latency(Telemetry::Domain::Constants::TREATMENTS_WITH_CONFIG_BY_FLAG_SETS, bucket)
|
|
468
|
+
when TRACK
|
|
469
|
+
@telemetry_evaluation_producer.record_latency(Telemetry::Domain::Constants::TRACK, bucket)
|
|
470
|
+
end
|
|
471
|
+
end
|
|
266
472
|
|
|
267
|
-
|
|
268
|
-
|
|
473
|
+
def record_exception(method)
|
|
474
|
+
case method
|
|
475
|
+
when GET_TREATMENT
|
|
476
|
+
@telemetry_evaluation_producer.record_exception(Telemetry::Domain::Constants::TREATMENT)
|
|
477
|
+
when GET_TREATMENTS
|
|
478
|
+
@telemetry_evaluation_producer.record_exception(Telemetry::Domain::Constants::TREATMENTS)
|
|
479
|
+
when GET_TREATMENT_WITH_CONFIG
|
|
480
|
+
@telemetry_evaluation_producer.record_exception(Telemetry::Domain::Constants::TREATMENT_WITH_CONFIG)
|
|
481
|
+
when GET_TREATMENTS_WITH_CONFIG
|
|
482
|
+
@telemetry_evaluation_producer.record_exception(Telemetry::Domain::Constants::TREATMENTS_WITH_CONFIG)
|
|
483
|
+
when GET_TREATMENTS_BY_FLAG_SET
|
|
484
|
+
@telemetry_evaluation_producer.record_exception(Telemetry::Domain::Constants::TREATMENTS_BY_FLAG_SET)
|
|
485
|
+
when GET_TREATMENTS_BY_FLAG_SETS
|
|
486
|
+
@telemetry_evaluation_producer.record_exception(Telemetry::Domain::Constants::TREATMENTS_BY_FLAG_SETS)
|
|
487
|
+
when GET_TREATMENTS_WITH_CONFIG_BY_FLAG_SET
|
|
488
|
+
@telemetry_evaluation_producer.record_exception(Telemetry::Domain::Constants::TREATMENTS_WITH_CONFIG_BY_FLAG_SET)
|
|
489
|
+
when GET_TREATMENTS_WITH_CONFIG_BY_FLAG_SETS
|
|
490
|
+
@telemetry_evaluation_producer.record_exception(Telemetry::Domain::Constants::TREATMENTS_WITH_CONFIG_BY_FLAG_SETS)
|
|
491
|
+
when TRACK
|
|
492
|
+
@telemetry_evaluation_producer.record_exception(Telemetry::Domain::Constants::TRACK)
|
|
493
|
+
end
|
|
494
|
+
end
|
|
269
495
|
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
496
|
+
def check_fallback_treatment(feature_name, label)
|
|
497
|
+
return {
|
|
498
|
+
label: (label != '')? label : nil,
|
|
499
|
+
treatment: Engine::Models::Treatment::CONTROL,
|
|
500
|
+
config: nil,
|
|
501
|
+
change_number: nil
|
|
502
|
+
} unless feature_name.is_a?(Symbol) || feature_name.is_a?(String)
|
|
503
|
+
|
|
504
|
+
fallback_treatment = @fallback_treatment_calculator.resolve(feature_name.to_sym, label)
|
|
505
|
+
|
|
506
|
+
{
|
|
507
|
+
label: (label != '')? fallback_treatment.label : nil,
|
|
508
|
+
treatment: fallback_treatment.treatment,
|
|
509
|
+
config: get_fallback_config(fallback_treatment),
|
|
510
|
+
change_number: nil
|
|
511
|
+
}
|
|
512
|
+
end
|
|
274
513
|
|
|
275
|
-
|
|
514
|
+
def get_treatment_without_config(treatment)
|
|
515
|
+
{
|
|
516
|
+
label: treatment[:label],
|
|
517
|
+
treatment: treatment[:treatment],
|
|
518
|
+
}
|
|
519
|
+
end
|
|
276
520
|
|
|
277
|
-
|
|
521
|
+
def get_fallback_config(fallback_treatment)
|
|
522
|
+
if fallback_treatment.config != nil
|
|
523
|
+
return fallback_treatment.config
|
|
278
524
|
end
|
|
279
525
|
|
|
280
|
-
|
|
526
|
+
return nil
|
|
281
527
|
end
|
|
528
|
+
|
|
282
529
|
end
|
|
283
530
|
end
|