splitclient-rb 8.2.0 → 8.3.0.pre.rc2
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/lib/splitclient-rb/cache/fetchers/split_fetcher.rb +2 -29
- data/lib/splitclient-rb/cache/filter/flag_set_filter.rb +40 -0
- 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/splits_repository.rb +100 -39
- data/lib/splitclient-rb/cache/stores/localhost_split_store.rb +1 -1
- data/lib/splitclient-rb/clients/split_client.rb +165 -81
- data/lib/splitclient-rb/engine/api/splits.rb +9 -3
- data/lib/splitclient-rb/engine/matchers/dependency_matcher.rb +1 -1
- data/lib/splitclient-rb/engine/parser/evaluator.rb +15 -21
- data/lib/splitclient-rb/exceptions.rb +11 -0
- data/lib/splitclient-rb/helpers/repository_helper.rb +23 -0
- data/lib/splitclient-rb/split_config.rb +22 -6
- data/lib/splitclient-rb/split_factory.rb +32 -9
- data/lib/splitclient-rb/sse/workers/splits_worker.rb +2 -9
- data/lib/splitclient-rb/telemetry/domain/constants.rb +4 -0
- data/lib/splitclient-rb/telemetry/domain/structs.rb +4 -4
- data/lib/splitclient-rb/telemetry/memory/memory_synchronizer.rb +18 -2
- data/lib/splitclient-rb/telemetry/redis/redis_synchronizer.rb +0 -1
- data/lib/splitclient-rb/telemetry/storages/memory.rb +12 -0
- data/lib/splitclient-rb/telemetry/synchronizer.rb +6 -2
- data/lib/splitclient-rb/validators.rb +63 -3
- data/lib/splitclient-rb/version.rb +1 -1
- data/lib/splitclient-rb.rb +4 -0
- metadata +8 -4
@@ -26,8 +26,19 @@ module SplitIoClient
|
|
26
26
|
end
|
27
27
|
|
28
28
|
@api_key = api_key
|
29
|
+
|
30
|
+
store_flag_sets = config_hash.key?(:flag_sets_filter) ? config_hash[:flag_sets_filter] : []
|
31
|
+
store_flag_sets = [] if !store_flag_sets.is_a?(Array)
|
32
|
+
flag_sets_count = 0
|
33
|
+
flag_sets_invalid = 0
|
34
|
+
|
29
35
|
@config = SplitConfig.new(config_hash.merge(localhost_mode: @api_key == LOCALHOST_API_KEY ))
|
30
36
|
|
37
|
+
if config_hash.key?(:flag_sets_filter)
|
38
|
+
flag_sets_count = store_flag_sets.length()
|
39
|
+
flag_sets_invalid = flag_sets_count - @config.flag_sets_filter.length()
|
40
|
+
end
|
41
|
+
|
31
42
|
raise 'Invalid SDK mode' unless valid_mode
|
32
43
|
|
33
44
|
validate_api_key
|
@@ -35,17 +46,20 @@ module SplitIoClient
|
|
35
46
|
register_factory
|
36
47
|
|
37
48
|
build_telemetry_components
|
49
|
+
build_flag_sets_filter
|
38
50
|
build_repositories
|
39
|
-
build_telemetry_synchronizer
|
51
|
+
build_telemetry_synchronizer(flag_sets_count, flag_sets_invalid)
|
40
52
|
build_impressions_sender_adapter
|
41
53
|
build_unique_keys_tracker
|
42
54
|
build_impressions_components
|
43
55
|
|
44
56
|
@status_manager = Engine::StatusManager.new(@config)
|
57
|
+
@split_validator = SplitIoClient::Validators.new(@config)
|
58
|
+
@evaluator = Engine::Parser::Evaluator.new(@segments_repository, @splits_repository, @config)
|
45
59
|
|
46
60
|
start!
|
47
61
|
|
48
|
-
@client = SplitClient.new(@api_key, repositories, @status_manager, @config, @impressions_manager, @evaluation_producer)
|
62
|
+
@client = SplitClient.new(@api_key, repositories, @status_manager, @config, @impressions_manager, @evaluation_producer, @evaluator, @split_validator)
|
49
63
|
@manager = SplitManager.new(@splits_repository, @status_manager, @config)
|
50
64
|
end
|
51
65
|
|
@@ -55,11 +69,11 @@ module SplitIoClient
|
|
55
69
|
if @config.consumer?
|
56
70
|
build_synchronizer
|
57
71
|
build_sync_manager
|
58
|
-
|
72
|
+
|
59
73
|
@sync_manager.start_consumer
|
60
74
|
return
|
61
75
|
end
|
62
|
-
|
76
|
+
|
63
77
|
build_fetchers
|
64
78
|
build_synchronizer
|
65
79
|
build_streaming_components
|
@@ -135,7 +149,7 @@ module SplitIoClient
|
|
135
149
|
end
|
136
150
|
|
137
151
|
def repositories
|
138
|
-
{
|
152
|
+
{
|
139
153
|
splits: @splits_repository,
|
140
154
|
segments: @segments_repository,
|
141
155
|
impressions: @impressions_repository,
|
@@ -188,7 +202,7 @@ module SplitIoClient
|
|
188
202
|
segments_worker = SSE::Workers::SegmentsWorker.new(@synchronizer, @config, @segments_repository)
|
189
203
|
notification_manager_keeper = SSE::NotificationManagerKeeper.new(@config, @runtime_producer, @push_status_queue)
|
190
204
|
notification_processor = SSE::NotificationProcessor.new(@config, splits_worker, segments_worker)
|
191
|
-
event_parser = SSE::EventSource::EventParser.new(config)
|
205
|
+
event_parser = SSE::EventSource::EventParser.new(config)
|
192
206
|
sse_client = SSE::EventSource::Client.new(@config, @api_key, @runtime_producer, event_parser, notification_manager_keeper, notification_processor, @push_status_queue)
|
193
207
|
@sse_handler = SSE::SSEHandler.new(@config, splits_worker, segments_worker, sse_client)
|
194
208
|
@push_manager = Engine::PushManager.new(@config, @sse_handler, @api_key, @runtime_producer)
|
@@ -199,15 +213,20 @@ module SplitIoClient
|
|
199
213
|
end
|
200
214
|
|
201
215
|
def build_repositories
|
202
|
-
|
216
|
+
if @config.cache_adapter.is_a? SplitIoClient::Cache::Adapters::RedisAdapter
|
217
|
+
@flag_sets_repository = SplitIoClient::Cache::Repositories::RedisFlagSetsRepository.new(@config)
|
218
|
+
else
|
219
|
+
@flag_sets_repository = SplitIoClient::Cache::Repositories::MemoryFlagSetsRepository.new(@config.flag_sets_filter)
|
220
|
+
end
|
221
|
+
@splits_repository = SplitsRepository.new(@config, @flag_sets_repository, @flag_sets_filter)
|
203
222
|
@segments_repository = SegmentsRepository.new(@config)
|
204
223
|
@impressions_repository = ImpressionsRepository.new(@config)
|
205
224
|
@events_repository = EventsRepository.new(@config, @api_key, @runtime_producer)
|
206
225
|
end
|
207
226
|
|
208
|
-
def build_telemetry_synchronizer
|
227
|
+
def build_telemetry_synchronizer(flag_sets, flag_sets_invalid)
|
209
228
|
@telemetry_api = Api::TelemetryApi.new(@config, @api_key, @runtime_producer)
|
210
|
-
@telemetry_synchronizer = Telemetry::Synchronizer.new(@config, @telemetry_consumers, @init_producer, repositories, @telemetry_api)
|
229
|
+
@telemetry_synchronizer = Telemetry::Synchronizer.new(@config, @telemetry_consumers, @init_producer, repositories, @telemetry_api, flag_sets, flag_sets_invalid)
|
211
230
|
end
|
212
231
|
|
213
232
|
def build_unique_keys_tracker
|
@@ -251,5 +270,9 @@ module SplitIoClient
|
|
251
270
|
|
252
271
|
@impressions_manager = Engine::Common::ImpressionManager.new(@config, @impressions_repository, @impression_counter, @runtime_producer, @impression_observer, @unique_keys_tracker)
|
253
272
|
end
|
273
|
+
|
274
|
+
def build_flag_sets_filter
|
275
|
+
@flag_sets_filter = SplitIoClient::Cache::Filter::FlagSetsFilter.new(@config.flag_sets_filter)
|
276
|
+
end
|
254
277
|
end
|
255
278
|
end
|
@@ -66,15 +66,9 @@ module SplitIoClient
|
|
66
66
|
return false unless !notification.data['d'].nil? && @feature_flags_repository.get_change_number == notification.data['pcn']
|
67
67
|
|
68
68
|
new_split = return_split_from_json(notification)
|
69
|
-
|
70
|
-
|
71
|
-
else
|
72
|
-
@feature_flags_repository.add_split(new_split)
|
69
|
+
SplitIoClient::Helpers::RepositoryHelper.update_feature_flag_repository(@feature_flags_repository, [new_split], notification.data['changeNumber'], @config)
|
70
|
+
fetch_segments_if_not_exists(new_split)
|
73
71
|
|
74
|
-
fetch_segments_if_not_exists(new_split)
|
75
|
-
end
|
76
|
-
|
77
|
-
@feature_flags_repository.set_change_number(notification.data['changeNumber'])
|
78
72
|
@telemetry_runtime_producer.record_updates_from_sse(Telemetry::Domain::Constants::SPLITS)
|
79
73
|
|
80
74
|
true
|
@@ -98,7 +92,6 @@ module SplitIoClient
|
|
98
92
|
|
99
93
|
def return_split_from_json(notification)
|
100
94
|
split_json = Helpers::DecryptionHelper.get_encoded_definition(notification.data['c'], notification.data['d'])
|
101
|
-
|
102
95
|
JSON.parse(split_json, symbolize_names: true)
|
103
96
|
end
|
104
97
|
|
@@ -35,6 +35,10 @@ module SplitIoClient
|
|
35
35
|
TREATMENTS = 'treatments'
|
36
36
|
TREATMENT_WITH_CONFIG = 'treatmentWithConfig'
|
37
37
|
TREATMENTS_WITH_CONFIG = 'treatmentsWithConfig'
|
38
|
+
TREATMENTS_BY_FLAG_SET = 'treatmentsByFlagSet'
|
39
|
+
TREATMENTS_BY_FLAG_SETS = 'treatmentsByFlagSets'
|
40
|
+
TREATMENTS_WITH_CONFIG_BY_FLAG_SET = 'treatmentWithConfigByFlagSet'
|
41
|
+
TREATMENTS_WITH_CONFIG_BY_FLAG_SETS = 'treatmentsWithConfigByFlagSets'
|
38
42
|
TRACK = 'track'
|
39
43
|
|
40
44
|
SPLITS = 'splits'
|
@@ -16,8 +16,8 @@ module SplitIoClient
|
|
16
16
|
# om: operationMode, st: storage, af: activeFactories, rf: redundantActiveFactories, t: tags, se: streamingEnabled,
|
17
17
|
# rr: refreshRate, uo: urlOverrides, iq: impressionsQueueSize, eq: eventsQueueSize, im: impressionsMode,
|
18
18
|
# il: impressionListenerEnabled, hp: httpProxyDetected, tr: timeUntilSdkReady, bt: burTimeouts,
|
19
|
-
# nr: sdkNotReadyUsage, i: integrations
|
20
|
-
ConfigInit = Struct.new(:om, :st, :af, :rf, :t, :se, :rr, :uo, :iq, :eq, :im, :il, :hp, :tr, :bt, :nr, :i)
|
19
|
+
# nr: sdkNotReadyUsage, i: integrations, fsT: Total flagsets, fsI: Invalid flagsets
|
20
|
+
ConfigInit = Struct.new(:om, :st, :af, :rf, :t, :fsT, :fsI, :se, :rr, :uo, :iq, :eq, :im, :il, :hp, :tr, :bt, :nr, :i)
|
21
21
|
|
22
22
|
# ls: lastSynchronization, ml: clientMethodLatencies, me: clientMethodExceptions, he: httpErros, hl: httpLatencies,
|
23
23
|
# tr: tokenRefreshes, ar: authRejections, iq: impressionsQueued, ide: impressionsDeduped, idr: impressionsDropped,
|
@@ -26,8 +26,8 @@ module SplitIoClient
|
|
26
26
|
Usage = Struct.new(:ls, :ml, :me, :he, :hl, :tr, :ar, :iq, :ide, :idr, :spc, :sec, :skc, :sl, :eq, :ed, :se, :t, :ufs)
|
27
27
|
|
28
28
|
# t: treatment, ts: treatments, tc: treatmentWithConfig, tcs: treatmentsWithConfig, tr: track
|
29
|
-
ClientMethodLatencies = Struct.new(:t, :ts, :tc, :tcs, :tr)
|
30
|
-
ClientMethodExceptions = Struct.new(:t, :ts, :tc, :tcs, :tr)
|
29
|
+
ClientMethodLatencies = Struct.new(:t, :ts, :tc, :tcs, :tf, :tfs, :tcf, :tcfs, :tr)
|
30
|
+
ClientMethodExceptions = Struct.new(:t, :ts, :tc, :tcs, :tf, :tfs, :tcf, :tcfs, :tr)
|
31
31
|
|
32
32
|
# sp: splits
|
33
33
|
UpdatesFromSSE = Struct.new(:sp)
|
@@ -6,7 +6,9 @@ module SplitIoClient
|
|
6
6
|
def initialize(config,
|
7
7
|
telemtry_consumers,
|
8
8
|
repositories,
|
9
|
-
telemetry_api
|
9
|
+
telemetry_api,
|
10
|
+
flag_sets,
|
11
|
+
flag_sets_invalid)
|
10
12
|
@config = config
|
11
13
|
@telemetry_init_consumer = telemtry_consumers[:init]
|
12
14
|
@telemetry_runtime_consumer = telemtry_consumers[:runtime]
|
@@ -14,6 +16,8 @@ module SplitIoClient
|
|
14
16
|
@splits_repository = repositories[:splits]
|
15
17
|
@segments_repository = repositories[:segments]
|
16
18
|
@telemetry_api = telemetry_api
|
19
|
+
@flag_sets = flag_sets
|
20
|
+
@flag_sets_invalid = flag_sets_invalid
|
17
21
|
end
|
18
22
|
|
19
23
|
def synchronize_stats
|
@@ -64,6 +68,8 @@ module SplitIoClient
|
|
64
68
|
active_factories,
|
65
69
|
redundant_active_factories,
|
66
70
|
@telemetry_runtime_consumer.pop_tags,
|
71
|
+
@flag_sets,
|
72
|
+
@flag_sets_invalid,
|
67
73
|
@config.streaming_enabled,
|
68
74
|
rates,
|
69
75
|
url_overrides,
|
@@ -113,7 +119,9 @@ module SplitIoClient
|
|
113
119
|
bT: init.bt,
|
114
120
|
nR: init.nr,
|
115
121
|
t: init.t,
|
116
|
-
i: init.i
|
122
|
+
i: init.i,
|
123
|
+
fsT: init.fsT,
|
124
|
+
fsI: init.fsI
|
117
125
|
}
|
118
126
|
end
|
119
127
|
|
@@ -125,6 +133,10 @@ module SplitIoClient
|
|
125
133
|
ts: usage.ml[Telemetry::Domain::Constants::TREATMENTS],
|
126
134
|
tc: usage.ml[Telemetry::Domain::Constants::TREATMENT_WITH_CONFIG],
|
127
135
|
tcs: usage.ml[Telemetry::Domain::Constants::TREATMENTS_WITH_CONFIG],
|
136
|
+
tf: usage.ml[Telemetry::Domain::Constants::TREATMENTS_BY_FLAG_SET],
|
137
|
+
tfs: usage.ml[Telemetry::Domain::Constants::TREATMENTS_BY_FLAG_SETS],
|
138
|
+
tcf: usage.ml[Telemetry::Domain::Constants::TREATMENTS_WITH_CONFIG_BY_FLAG_SET],
|
139
|
+
tcfs: usage.ml[Telemetry::Domain::Constants::TREATMENTS_WITH_CONFIG_BY_FLAG_SETS],
|
128
140
|
tr: usage.ml[Telemetry::Domain::Constants::TRACK]
|
129
141
|
},
|
130
142
|
mE: {
|
@@ -132,6 +144,10 @@ module SplitIoClient
|
|
132
144
|
ts: usage.me[Telemetry::Domain::Constants::TREATMENTS],
|
133
145
|
tc: usage.me[Telemetry::Domain::Constants::TREATMENT_WITH_CONFIG],
|
134
146
|
tcs: usage.me[Telemetry::Domain::Constants::TREATMENTS_WITH_CONFIG],
|
147
|
+
tf: usage.me[Telemetry::Domain::Constants::TREATMENTS_BY_FLAG_SET],
|
148
|
+
tfs: usage.me[Telemetry::Domain::Constants::TREATMENTS_BY_FLAG_SETS],
|
149
|
+
tcf: usage.me[Telemetry::Domain::Constants::TREATMENTS_WITH_CONFIG_BY_FLAG_SET],
|
150
|
+
tcfs: usage.me[Telemetry::Domain::Constants::TREATMENTS_WITH_CONFIG_BY_FLAG_SETS],
|
135
151
|
tr: usage.me[Telemetry::Domain::Constants::TRACK]
|
136
152
|
},
|
137
153
|
hE: {
|
@@ -18,7 +18,6 @@ module SplitIoClient
|
|
18
18
|
redundant_active_factories ||= SplitIoClient.split_factory_registry.redundant_active_factories
|
19
19
|
|
20
20
|
init_config = ConfigInit.new(@config.mode, 'redis', active_factories, redundant_active_factories, tags)
|
21
|
-
|
22
21
|
@telemetry_init_producer.record_config(init_config)
|
23
22
|
rescue StandardError => e
|
24
23
|
@config.log_found_exception(__method__.to_s, e)
|
@@ -38,22 +38,34 @@ module SplitIoClient
|
|
38
38
|
|
39
39
|
def init_latencies
|
40
40
|
@latencies = Concurrent::Array.new
|
41
|
+
treatment_with_config_by_flag_set_const = Domain::Constants::TREATMENTS_WITH_CONFIG_BY_FLAG_SET
|
42
|
+
treatment_with_config_by_flag_sets_const = Domain::Constants::TREATMENTS_WITH_CONFIG_BY_FLAG_SETS
|
41
43
|
|
42
44
|
array_size = BinarySearchLatencyTracker::BUCKETS.length
|
43
45
|
@latencies << { method: Domain::Constants::TREATMENT, latencies: Concurrent::Array.new(array_size, 0) }
|
44
46
|
@latencies << { method: Domain::Constants::TREATMENTS, latencies: Concurrent::Array.new(array_size, 0) }
|
45
47
|
@latencies << { method: Domain::Constants::TREATMENT_WITH_CONFIG, latencies: Concurrent::Array.new(array_size, 0) }
|
46
48
|
@latencies << { method: Domain::Constants::TREATMENTS_WITH_CONFIG, latencies: Concurrent::Array.new(array_size, 0) }
|
49
|
+
@latencies << { method: Domain::Constants::TREATMENTS_BY_FLAG_SET, latencies: Concurrent::Array.new(array_size, 0) }
|
50
|
+
@latencies << { method: Domain::Constants::TREATMENTS_BY_FLAG_SETS, latencies: Concurrent::Array.new(array_size, 0) }
|
51
|
+
@latencies << { method: treatment_with_config_by_flag_set_const, latencies: Concurrent::Array.new(array_size, 0) }
|
52
|
+
@latencies << { method: treatment_with_config_by_flag_sets_const, latencies: Concurrent::Array.new(array_size, 0) }
|
47
53
|
@latencies << { method: Domain::Constants::TRACK, latencies: Concurrent::Array.new(array_size, 0) }
|
48
54
|
end
|
49
55
|
|
50
56
|
def init_exceptions
|
51
57
|
@exceptions = Concurrent::Array.new
|
58
|
+
treatment_with_config_by_flag_set_const = Domain::Constants::TREATMENTS_WITH_CONFIG_BY_FLAG_SET
|
59
|
+
treatment_with_config_by_flag_sets_const = Domain::Constants::TREATMENTS_WITH_CONFIG_BY_FLAG_SETS
|
52
60
|
|
53
61
|
@exceptions << { method: Domain::Constants::TREATMENT, exceptions: Concurrent::AtomicFixnum.new(0) }
|
54
62
|
@exceptions << { method: Domain::Constants::TREATMENTS, exceptions: Concurrent::AtomicFixnum.new(0) }
|
55
63
|
@exceptions << { method: Domain::Constants::TREATMENT_WITH_CONFIG, exceptions: Concurrent::AtomicFixnum.new(0) }
|
56
64
|
@exceptions << { method: Domain::Constants::TREATMENTS_WITH_CONFIG, exceptions: Concurrent::AtomicFixnum.new(0) }
|
65
|
+
@exceptions << { method: Domain::Constants::TREATMENTS_BY_FLAG_SET, exceptions: Concurrent::AtomicFixnum.new(0) }
|
66
|
+
@exceptions << { method: Domain::Constants::TREATMENTS_BY_FLAG_SETS, exceptions: Concurrent::AtomicFixnum.new(0) }
|
67
|
+
@exceptions << { method: treatment_with_config_by_flag_set_const, exceptions: Concurrent::AtomicFixnum.new(0) }
|
68
|
+
@exceptions << { method: treatment_with_config_by_flag_sets_const, exceptions: Concurrent::AtomicFixnum.new(0) }
|
57
69
|
@exceptions << { method: Domain::Constants::TRACK, exceptions: Concurrent::AtomicFixnum.new(0) }
|
58
70
|
end
|
59
71
|
|
@@ -12,7 +12,9 @@ module SplitIoClient
|
|
12
12
|
telemtry_consumers,
|
13
13
|
telemetry_init_producer,
|
14
14
|
repositories,
|
15
|
-
telemetry_api
|
15
|
+
telemetry_api,
|
16
|
+
flag_sets,
|
17
|
+
flag_sets_invalid)
|
16
18
|
@synchronizer = case config.telemetry_adapter.class.to_s
|
17
19
|
when 'SplitIoClient::Cache::Adapters::RedisAdapter'
|
18
20
|
SplitIoClient::Telemetry::RedisSynchronizer.new(config,
|
@@ -21,7 +23,9 @@ module SplitIoClient
|
|
21
23
|
SplitIoClient::Telemetry::MemorySynchronizer.new(config,
|
22
24
|
telemtry_consumers,
|
23
25
|
repositories,
|
24
|
-
telemetry_api
|
26
|
+
telemetry_api,
|
27
|
+
flag_sets,
|
28
|
+
flag_sets_invalid)
|
25
29
|
end
|
26
30
|
end
|
27
31
|
end
|
@@ -3,6 +3,8 @@
|
|
3
3
|
module SplitIoClient
|
4
4
|
class Validators
|
5
5
|
|
6
|
+
Flagset_regex = /^[a-z0-9][_a-z0-9]{0,49}$/
|
7
|
+
|
6
8
|
def initialize(config)
|
7
9
|
@config = config
|
8
10
|
end
|
@@ -15,8 +17,12 @@ module SplitIoClient
|
|
15
17
|
valid_attributes?(method, attributes)
|
16
18
|
end
|
17
19
|
|
18
|
-
def valid_get_treatments_parameters(method, split_names)
|
19
|
-
|
20
|
+
def valid_get_treatments_parameters(method, key, split_names, matching_key, bucketing_key, attributes)
|
21
|
+
valid_key?(method, key) &&
|
22
|
+
valid_split_names?(method, split_names)
|
23
|
+
valid_matching_key?(method, matching_key) &&
|
24
|
+
valid_bucketing_key?(method, key, bucketing_key) &&
|
25
|
+
valid_attributes?(method, attributes)
|
20
26
|
end
|
21
27
|
|
22
28
|
def valid_track_parameters(key, traffic_type_name, event_type, value, properties)
|
@@ -38,6 +44,39 @@ module SplitIoClient
|
|
38
44
|
true
|
39
45
|
end
|
40
46
|
|
47
|
+
def valid_flag_sets(method, flag_sets)
|
48
|
+
if flag_sets.nil? || !flag_sets.is_a?(Array)
|
49
|
+
@config.logger.error("#{method}: FlagSets must be a non-empty list.")
|
50
|
+
return []
|
51
|
+
end
|
52
|
+
if flag_sets.empty?
|
53
|
+
@config.logger.error("#{method}: FlagSets must be a non-empty list.")
|
54
|
+
return []
|
55
|
+
end
|
56
|
+
without_nil = Array.new
|
57
|
+
flag_sets.each { |flag_set|
|
58
|
+
without_nil.push(flag_set) if !flag_set.nil?
|
59
|
+
log_nil("flag set", method) if flag_set.nil?
|
60
|
+
}
|
61
|
+
if without_nil.length() == 0
|
62
|
+
log_invalid_flag_set_type(method)
|
63
|
+
return []
|
64
|
+
end
|
65
|
+
valid_flag_sets = Set[]
|
66
|
+
without_nil.compact.uniq.select do |flag_set|
|
67
|
+
if flag_set.nil? || !flag_set.is_a?(String)
|
68
|
+
log_invalid_flag_set_type(method)
|
69
|
+
elsif flag_set.is_a?(String) && flag_set.empty?
|
70
|
+
log_invalid_flag_set_type(method)
|
71
|
+
elsif !flag_set.empty? && string_match?(flag_set.strip.downcase, method)
|
72
|
+
valid_flag_sets.add(flag_set.strip.downcase)
|
73
|
+
else
|
74
|
+
log_invalid_flag_set_type(method)
|
75
|
+
end
|
76
|
+
end
|
77
|
+
!valid_flag_sets.empty? ? valid_flag_sets.to_a.sort : []
|
78
|
+
end
|
79
|
+
|
41
80
|
private
|
42
81
|
|
43
82
|
def string?(value)
|
@@ -52,8 +91,25 @@ module SplitIoClient
|
|
52
91
|
(value.is_a?(Numeric) && !value.to_f.nan?) || string?(value)
|
53
92
|
end
|
54
93
|
|
94
|
+
def string_match?(value, method)
|
95
|
+
if Flagset_regex.match(value) == nil
|
96
|
+
log_invalid_match(value, method)
|
97
|
+
false
|
98
|
+
else
|
99
|
+
true
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
def log_invalid_match(key, method)
|
104
|
+
@config.logger.error("#{method}: you passed #{key}, flag set must adhere to the regular expression #{Flagset_regex}. " +
|
105
|
+
"This means flag set must be alphanumeric, cannot be more than 50 characters long, and can only include a dash, underscore, " +
|
106
|
+
"period, or colon as separators of alphanumeric characters.")
|
107
|
+
end
|
108
|
+
|
55
109
|
def log_nil(key, method)
|
56
|
-
|
110
|
+
msg_text = String.new("#{method}: you passed a nil #{key}, #{key} must be a non-empty String")
|
111
|
+
msg_text << " or a Symbol" if !key.equal?("flag set")
|
112
|
+
@config.logger.error(msg_text)
|
57
113
|
end
|
58
114
|
|
59
115
|
def log_empty_string(key, method)
|
@@ -64,6 +120,10 @@ module SplitIoClient
|
|
64
120
|
@config.logger.error("#{method}: you passed an invalid #{key} type, #{key} must be a non-empty String or a Symbol")
|
65
121
|
end
|
66
122
|
|
123
|
+
def log_invalid_flag_set_type(method)
|
124
|
+
@config.logger.warn("#{method}: you passed an invalid flag set type, flag set must be a non-empty String")
|
125
|
+
end
|
126
|
+
|
67
127
|
def log_convert_numeric(key, method, value)
|
68
128
|
@config.logger.warn("#{method}: #{key} \"#{value}\" is not of type String, converting")
|
69
129
|
end
|
data/lib/splitclient-rb.rb
CHANGED
@@ -14,6 +14,7 @@ require 'splitclient-rb/cache/fetchers/segment_fetcher'
|
|
14
14
|
require 'splitclient-rb/cache/fetchers/split_fetcher'
|
15
15
|
require 'splitclient-rb/cache/filter/bloom_filter'
|
16
16
|
require 'splitclient-rb/cache/filter/filter_adapter'
|
17
|
+
require 'splitclient-rb/cache/filter/flag_set_filter'
|
17
18
|
require 'splitclient-rb/cache/hashers/impression_hasher'
|
18
19
|
require 'splitclient-rb/cache/observers/impression_observer'
|
19
20
|
require 'splitclient-rb/cache/observers/noop_impression_observer'
|
@@ -24,6 +25,8 @@ require 'splitclient-rb/cache/repositories/events_repository'
|
|
24
25
|
require 'splitclient-rb/cache/repositories/impressions_repository'
|
25
26
|
require 'splitclient-rb/cache/repositories/events/memory_repository'
|
26
27
|
require 'splitclient-rb/cache/repositories/events/redis_repository'
|
28
|
+
require 'splitclient-rb/cache/repositories/flag_sets/memory_repository'
|
29
|
+
require 'splitclient-rb/cache/repositories/flag_sets/redis_repository'
|
27
30
|
require 'splitclient-rb/cache/repositories/impressions/memory_repository'
|
28
31
|
require 'splitclient-rb/cache/repositories/impressions/redis_repository'
|
29
32
|
require 'splitclient-rb/cache/senders/impressions_formatter'
|
@@ -43,6 +46,7 @@ require 'splitclient-rb/managers/split_manager'
|
|
43
46
|
require 'splitclient-rb/helpers/thread_helper'
|
44
47
|
require 'splitclient-rb/helpers/decryption_helper'
|
45
48
|
require 'splitclient-rb/helpers/util'
|
49
|
+
require 'splitclient-rb/helpers/repository_helper'
|
46
50
|
require 'splitclient-rb/split_factory'
|
47
51
|
require 'splitclient-rb/split_factory_builder'
|
48
52
|
require 'splitclient-rb/split_config'
|
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: 8.
|
4
|
+
version: 8.3.0.pre.rc2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Split Software
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-
|
11
|
+
date: 2023-12-04 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: allocation_stats
|
@@ -443,12 +443,15 @@ files:
|
|
443
443
|
- lib/splitclient-rb/cache/fetchers/split_fetcher.rb
|
444
444
|
- lib/splitclient-rb/cache/filter/bloom_filter.rb
|
445
445
|
- lib/splitclient-rb/cache/filter/filter_adapter.rb
|
446
|
+
- lib/splitclient-rb/cache/filter/flag_set_filter.rb
|
446
447
|
- lib/splitclient-rb/cache/hashers/impression_hasher.rb
|
447
448
|
- lib/splitclient-rb/cache/observers/impression_observer.rb
|
448
449
|
- lib/splitclient-rb/cache/observers/noop_impression_observer.rb
|
449
450
|
- lib/splitclient-rb/cache/repositories/events/memory_repository.rb
|
450
451
|
- lib/splitclient-rb/cache/repositories/events/redis_repository.rb
|
451
452
|
- lib/splitclient-rb/cache/repositories/events_repository.rb
|
453
|
+
- lib/splitclient-rb/cache/repositories/flag_sets/memory_repository.rb
|
454
|
+
- lib/splitclient-rb/cache/repositories/flag_sets/redis_repository.rb
|
452
455
|
- lib/splitclient-rb/cache/repositories/impressions/memory_repository.rb
|
453
456
|
- lib/splitclient-rb/cache/repositories/impressions/redis_repository.rb
|
454
457
|
- lib/splitclient-rb/cache/repositories/impressions_repository.rb
|
@@ -519,6 +522,7 @@ files:
|
|
519
522
|
- lib/splitclient-rb/engine/synchronizer.rb
|
520
523
|
- lib/splitclient-rb/exceptions.rb
|
521
524
|
- lib/splitclient-rb/helpers/decryption_helper.rb
|
525
|
+
- lib/splitclient-rb/helpers/repository_helper.rb
|
522
526
|
- lib/splitclient-rb/helpers/thread_helper.rb
|
523
527
|
- lib/splitclient-rb/helpers/util.rb
|
524
528
|
- lib/splitclient-rb/managers/split_manager.rb
|
@@ -579,9 +583,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
579
583
|
version: 2.5.0
|
580
584
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
581
585
|
requirements:
|
582
|
-
- - "
|
586
|
+
- - ">"
|
583
587
|
- !ruby/object:Gem::Version
|
584
|
-
version:
|
588
|
+
version: 1.3.1
|
585
589
|
requirements: []
|
586
590
|
rubygems_version: 3.2.3
|
587
591
|
signing_key:
|