splitclient-rb 8.1.2.pre.rc1 → 8.1.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGES.txt +1 -1
- data/README.md +16 -10
- data/lib/splitclient-rb/cache/fetchers/split_fetcher.rb +5 -5
- data/lib/splitclient-rb/cache/stores/localhost_split_store.rb +2 -2
- data/lib/splitclient-rb/clients/split_client.rb +10 -10
- data/lib/splitclient-rb/engine/api/splits.rb +4 -4
- data/lib/splitclient-rb/engine/matchers/dependency_matcher.rb +5 -5
- data/lib/splitclient-rb/engine/synchronizer.rb +1 -1
- data/lib/splitclient-rb/managers/split_manager.rb +10 -10
- data/lib/splitclient-rb/sse/workers/splits_worker.rb +6 -6
- data/lib/splitclient-rb/validators.rb +1 -1
- data/lib/splitclient-rb/version.rb +1 -1
- metadata +4 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c062c9b9de400aef087ba151c0ca987d9a562e46cbc7d4305c3eb89215d63f06
|
4
|
+
data.tar.gz: 85ae608d05f60f87a824f9363bbbc5cda3b7a6da32bfee26d221ca0010b7e2f0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 693fbcc62d83b00fd945bc12a55a5b807c86ab07d3738399d3f203f3f6b75c4266c6f22cb92fddb840f35849095340ac9ee90c879ea52b389fa1678136b38102
|
7
|
+
data.tar.gz: ba91997fe5008f727eec7b6aaa41b90383efc0a8b1a3330ab9b4a76792508b97e13af3e6413c9f04246103f32e786baf46755db9bc67483621ae39a2f92daee6
|
data/CHANGES.txt
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
CHANGES
|
2
2
|
|
3
3
|
8.1.2 (May 15, 2023)
|
4
|
-
- Updated terminology on the SDKs codebase to be more aligned with current standard without causing a breaking change. The core change is the term split for feature flag on things like logs and
|
4
|
+
- Updated terminology on the SDKs codebase to be more aligned with current standard without causing a breaking change. The core change is the term split for feature flag on things like logs and IntelliSense comments.
|
5
5
|
|
6
6
|
8.1.1 (Mar 17, 2023)
|
7
7
|
- Added retries with backoff when the sdk tries to connect to the Streaming service and it is not available.
|
data/README.md
CHANGED
@@ -1,8 +1,9 @@
|
|
1
1
|
# Split SDK for Ruby
|
2
|
-
![
|
2
|
+
[![build status](https://github.com/splitio/ruby-client/actions/workflows/ci.yml/badge.svg?branch=master)](https://github.com/splitio/ruby-client/actions)
|
3
|
+
[![Documentation](https://img.shields.io/badge/ruby_client-documentation-informational)](https://help.split.io/hc/en-us/articles/360020673251-Ruby-SDK)
|
3
4
|
|
4
5
|
## Overview
|
5
|
-
This SDK is designed to work with Split, the platform for controlled rollouts, which serves features to your users via
|
6
|
+
This SDK is designed to work with Split, the platform for controlled rollouts, which serves features to your users via feature flags to manage your complete customer experience.
|
6
7
|
|
7
8
|
[![Twitter Follow](https://img.shields.io/twitter/follow/splitsoftware.svg?style=social&label=Follow&maxAge=1529000)](https://twitter.com/intent/follow?screen_name=splitsoftware)
|
8
9
|
|
@@ -21,7 +22,7 @@ Below is a simple example that describes the instantiation and most basic usage
|
|
21
22
|
```ruby
|
22
23
|
require 'splitclient-rb'
|
23
24
|
|
24
|
-
split_factory = SplitIoClient::SplitFactory.new('
|
25
|
+
split_factory = SplitIoClient::SplitFactory.new('YOUR_SDK_KEY')
|
25
26
|
split_client = split_factory.client
|
26
27
|
|
27
28
|
begin
|
@@ -30,7 +31,7 @@ rescue SplitIoClient::SDKBlockerTimeoutExpiredException
|
|
30
31
|
puts 'SDK is not ready. Decide whether to continue or abort execution'
|
31
32
|
end
|
32
33
|
|
33
|
-
treatment = split_client.get_treatment('CUSTOMER_ID', '
|
34
|
+
treatment = split_client.get_treatment('CUSTOMER_ID', 'FEATURE_FLAG_NAME');
|
34
35
|
|
35
36
|
if treatment == 'on'
|
36
37
|
# insert code here to show on treatment
|
@@ -60,16 +61,21 @@ To learn more about Split, contact hello@split.io, or get started with feature f
|
|
60
61
|
|
61
62
|
Split has built and maintains SDKs for:
|
62
63
|
|
64
|
+
* .NET [Github](https://github.com/splitio/dotnet-client) [Docs](https://help.split.io/hc/en-us/articles/360020240172--NET-SDK)
|
65
|
+
* Android [Github](https://github.com/splitio/android-client) [Docs](https://help.split.io/hc/en-us/articles/360020343291-Android-SDK)
|
66
|
+
* Angular [Github](https://github.com/splitio/angular-sdk-plugin) [Docs](https://help.split.io/hc/en-us/articles/6495326064397-Angular-utilities)
|
67
|
+
* GO [Github](https://github.com/splitio/go-client) [Docs](https://help.split.io/hc/en-us/articles/360020093652-Go-SDK)
|
68
|
+
* iOS [Github](https://github.com/splitio/ios-client) [Docs](https://help.split.io/hc/en-us/articles/360020401491-iOS-SDK)
|
63
69
|
* Java [Github](https://github.com/splitio/java-client) [Docs](https://help.split.io/hc/en-us/articles/360020405151-Java-SDK)
|
64
|
-
*
|
70
|
+
* JavaScript [Github](https://github.com/splitio/javascript-client) [Docs](https://help.split.io/hc/en-us/articles/360020448791-JavaScript-SDK)
|
71
|
+
* JavaScript for Browser [Github](https://github.com/splitio/javascript-browser-client) [Docs](https://help.split.io/hc/en-us/articles/360058730852-Browser-SDK)
|
65
72
|
* Node [Github](https://github.com/splitio/javascript-client) [Docs](https://help.split.io/hc/en-us/articles/360020564931-Node-js-SDK)
|
66
|
-
* .NET [Github](https://github.com/splitio/dotnet-client) [Docs](https://help.split.io/hc/en-us/articles/360020240172--NET-SDK)
|
67
|
-
* Ruby [Github](https://github.com/splitio/ruby-client) [Docs](https://help.split.io/hc/en-us/articles/360020673251-Ruby-SDK)
|
68
73
|
* PHP [Github](https://github.com/splitio/php-client) [Docs](https://help.split.io/hc/en-us/articles/360020350372-PHP-SDK)
|
69
74
|
* Python [Github](https://github.com/splitio/python-client) [Docs](https://help.split.io/hc/en-us/articles/360020359652-Python-SDK)
|
70
|
-
*
|
71
|
-
*
|
72
|
-
*
|
75
|
+
* React [Github](https://github.com/splitio/react-client) [Docs](https://help.split.io/hc/en-us/articles/360038825091-React-SDK)
|
76
|
+
* React Native [Github](https://github.com/splitio/react-native-client) [Docs](https://help.split.io/hc/en-us/articles/4406066357901-React-Native-SDK)
|
77
|
+
* Redux [Github](https://github.com/splitio/redux-client) [Docs](https://help.split.io/hc/en-us/articles/360038851551-Redux-SDK)
|
78
|
+
* Ruby [Github](https://github.com/splitio/ruby-client) [Docs](https://help.split.io/hc/en-us/articles/360020673251-Ruby-SDK)
|
73
79
|
|
74
80
|
For a comprehensive list of open source projects visit our [Github page](https://github.com/splitio?utf8=%E2%9C%93&query=%20only%3Apublic%20).
|
75
81
|
|
@@ -49,12 +49,12 @@ module SplitIoClient
|
|
49
49
|
|
50
50
|
def splits_thread
|
51
51
|
@config.threads[:split_fetcher] = Thread.new do
|
52
|
-
@config.logger.info('Starting
|
52
|
+
@config.logger.info('Starting feature flags fetcher service') if @config.debug_enabled
|
53
53
|
loop do
|
54
54
|
fetch_splits
|
55
55
|
|
56
56
|
sleep_for = SplitIoClient::Cache::Stores::StoreUtils.random_interval(@config.features_refresh_rate)
|
57
|
-
@config.logger.debug("
|
57
|
+
@config.logger.debug("Feature flags fetcher is sleeping for: #{sleep_for} seconds") if @config.debug_enabled
|
58
58
|
sleep(sleep_for)
|
59
59
|
end
|
60
60
|
end
|
@@ -66,7 +66,7 @@ module SplitIoClient
|
|
66
66
|
|
67
67
|
def add_split_unless_archived(split)
|
68
68
|
if Engine::Models::Split.archived?(split)
|
69
|
-
@config.logger.debug("Seeing archived
|
69
|
+
@config.logger.debug("Seeing archived feature flag #{split[:name]}") if @config.debug_enabled
|
70
70
|
|
71
71
|
remove_archived_split(split)
|
72
72
|
else
|
@@ -75,13 +75,13 @@ module SplitIoClient
|
|
75
75
|
end
|
76
76
|
|
77
77
|
def remove_archived_split(split)
|
78
|
-
@config.logger.debug("removing
|
78
|
+
@config.logger.debug("removing feature flag from store(#{split})") if @config.debug_enabled
|
79
79
|
|
80
80
|
@splits_repository.remove_split(split)
|
81
81
|
end
|
82
82
|
|
83
83
|
def store_split(split)
|
84
|
-
@config.logger.debug("storing
|
84
|
+
@config.logger.debug("storing feature flag (#{split[:name]})") if @config.debug_enabled
|
85
85
|
|
86
86
|
@splits_repository.add_split(split)
|
87
87
|
end
|
@@ -31,7 +31,7 @@ module SplitIoClient
|
|
31
31
|
|
32
32
|
def splits_thread
|
33
33
|
@config.threads[:split_store] = Thread.new do
|
34
|
-
@config.logger.info('Starting
|
34
|
+
@config.logger.info('Starting feature flags fetcher service')
|
35
35
|
loop do
|
36
36
|
store_splits
|
37
37
|
|
@@ -53,7 +53,7 @@ module SplitIoClient
|
|
53
53
|
end
|
54
54
|
|
55
55
|
def store_split(split)
|
56
|
-
@config.logger.debug("storing
|
56
|
+
@config.logger.debug("storing feature flag (#{split[:name]})") if @config.debug_enabled
|
57
57
|
|
58
58
|
@splits_repository.add_split(split)
|
59
59
|
end
|
@@ -11,11 +11,11 @@ module SplitIoClient
|
|
11
11
|
#
|
12
12
|
# Creates a new split client instance that connects to split.io API.
|
13
13
|
#
|
14
|
-
# @param
|
14
|
+
# @param sdk_key [String] the SDK key for your split account
|
15
15
|
#
|
16
16
|
# @return [SplitIoClient] split.io client instance
|
17
|
-
def initialize(
|
18
|
-
@api_key =
|
17
|
+
def initialize(sdk_key, repositories, status_manager, config, impressions_manager, telemetry_evaluation_producer)
|
18
|
+
@api_key = sdk_key
|
19
19
|
@splits_repository = repositories[:splits]
|
20
20
|
@segments_repository = repositories[:segments]
|
21
21
|
@impressions_repository = repositories[:impressions]
|
@@ -103,8 +103,8 @@ module SplitIoClient
|
|
103
103
|
|
104
104
|
if ready? && !@config.localhost_mode && !@splits_repository.traffic_type_exists(traffic_type_name)
|
105
105
|
@config.logger.warn("track: Traffic Type #{traffic_type_name} " \
|
106
|
-
"does not have any corresponding
|
107
|
-
'your events to a valid traffic type defined in the Split
|
106
|
+
"does not have any corresponding feature flags in this environment, make sure you're tracking " \
|
107
|
+
'your events to a valid traffic type defined in the Split user interface')
|
108
108
|
end
|
109
109
|
|
110
110
|
@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)
|
@@ -147,10 +147,10 @@ module SplitIoClient
|
|
147
147
|
if (split_name.is_a?(String) || split_name.is_a?(Symbol)) && !split_name.empty?
|
148
148
|
true
|
149
149
|
elsif split_name.is_a?(String) && split_name.empty?
|
150
|
-
@config.logger.warn("#{calling_method}: you passed an empty
|
150
|
+
@config.logger.warn("#{calling_method}: you passed an empty feature_flag_name, flag name must be a non-empty String or a Symbol")
|
151
151
|
false
|
152
152
|
else
|
153
|
-
@config.logger.warn("#{calling_method}: you passed an invalid
|
153
|
+
@config.logger.warn("#{calling_method}: you passed an invalid feature_flag_name, flag name must be a non-empty String or a Symbol")
|
154
154
|
false
|
155
155
|
end
|
156
156
|
end
|
@@ -200,7 +200,7 @@ module SplitIoClient
|
|
200
200
|
sanitized_split_names = sanitize_split_names(calling_method, split_names)
|
201
201
|
|
202
202
|
if sanitized_split_names.empty?
|
203
|
-
@config.logger.error("#{calling_method}:
|
203
|
+
@config.logger.error("#{calling_method}: feature_flag_names must be a non-empty Array")
|
204
204
|
return {}
|
205
205
|
end
|
206
206
|
|
@@ -258,7 +258,7 @@ module SplitIoClient
|
|
258
258
|
sanitized_split_name = split_name.to_s.strip
|
259
259
|
|
260
260
|
if split_name.to_s != sanitized_split_name
|
261
|
-
@config.logger.warn("#{calling_method}:
|
261
|
+
@config.logger.warn("#{calling_method}: feature_flag_name #{split_name} has extra whitespace, trimming")
|
262
262
|
split_name = sanitized_split_name
|
263
263
|
end
|
264
264
|
|
@@ -271,7 +271,7 @@ module SplitIoClient
|
|
271
271
|
|
272
272
|
if split.nil? && ready?
|
273
273
|
@config.logger.warn("#{calling_method}: you passed #{split_name} that " \
|
274
|
-
'does not exist in this environment, please double check what
|
274
|
+
'does not exist in this environment, please double check what feature flags exist in the Split user interface')
|
275
275
|
|
276
276
|
return parsed_treatment(multiple, control_treatment.merge({ label: Engine::Models::Label::NOT_FOUND }))
|
277
277
|
end
|
@@ -20,9 +20,9 @@ module SplitIoClient
|
|
20
20
|
result = splits_with_segment_names(response.body)
|
21
21
|
|
22
22
|
unless result[:splits].empty?
|
23
|
-
@config.split_logger.log_if_debug("#{result[:splits].length}
|
23
|
+
@config.split_logger.log_if_debug("#{result[:splits].length} feature flags retrieved. since=#{since}")
|
24
24
|
end
|
25
|
-
@config.split_logger.log_if_transport("
|
25
|
+
@config.split_logger.log_if_transport("Feature flag changes response: #{result.to_s}")
|
26
26
|
|
27
27
|
bucket = BinarySearchLatencyTracker.get_bucket((Time.now - start) * 1000.0)
|
28
28
|
@telemetry_runtime_producer.record_sync_latency(Telemetry::Domain::Constants::SPLIT_SYNC, bucket)
|
@@ -32,10 +32,10 @@ module SplitIoClient
|
|
32
32
|
else
|
33
33
|
@telemetry_runtime_producer.record_sync_error(Telemetry::Domain::Constants::SPLIT_SYNC, response.status)
|
34
34
|
|
35
|
-
@config.logger.error("Unexpected status code while fetching
|
35
|
+
@config.logger.error("Unexpected status code while fetching feature flags: #{response.status}. " \
|
36
36
|
'Check your API key and base URI')
|
37
37
|
|
38
|
-
raise 'Split SDK failed to connect to backend to fetch
|
38
|
+
raise 'Split SDK failed to connect to backend to fetch feature flags definitions'
|
39
39
|
end
|
40
40
|
end
|
41
41
|
|
@@ -4,18 +4,18 @@ module SplitIoClient
|
|
4
4
|
class DependencyMatcher
|
5
5
|
MATCHER_TYPE = 'IN_SPLIT_TREATMENT'
|
6
6
|
|
7
|
-
def initialize(
|
8
|
-
@
|
7
|
+
def initialize(feature_flag, treatments, logger)
|
8
|
+
@feature_flag = feature_flag
|
9
9
|
@treatments = treatments
|
10
10
|
@logger = logger
|
11
11
|
end
|
12
12
|
|
13
13
|
def match?(args)
|
14
14
|
keys = { matching_key: args[:matching_key], bucketing_key: args[:bucketing_key] }
|
15
|
-
evaluate = args[:evaluator].call(keys, @
|
15
|
+
evaluate = args[:evaluator].call(keys, @feature_flag, args[:attributes])
|
16
16
|
matches = @treatments.include?(evaluate[:treatment])
|
17
|
-
@logger.log_if_debug("[dependencyMatcher] Parent
|
18
|
-
with label #{evaluate[:label]}. #{@
|
17
|
+
@logger.log_if_debug("[dependencyMatcher] Parent feature flag #{@feature_flag} evaluated to #{evaluate[:treatment]} \
|
18
|
+
with label #{evaluate[:label]}. #{@feature_flag} evaluated treatment is part of [#{@treatments}] ? #{matches}.")
|
19
19
|
matches
|
20
20
|
end
|
21
21
|
|
@@ -201,7 +201,7 @@ module SplitIoClient
|
|
201
201
|
end
|
202
202
|
|
203
203
|
def sync_splits_and_segments
|
204
|
-
@config.logger.debug('Synchronizing
|
204
|
+
@config.logger.debug('Synchronizing feature flags and segments ...') if @config.debug_enabled
|
205
205
|
splits_result = @split_fetcher.fetch_splits
|
206
206
|
|
207
207
|
splits_result[:success] && @segment_fetcher.fetch_segments
|
@@ -50,31 +50,31 @@ module SplitIoClient
|
|
50
50
|
# method to get a split view
|
51
51
|
#
|
52
52
|
# @returns a split view
|
53
|
-
def split(
|
54
|
-
return unless @config.valid_mode && @splits_repository && @config.split_validator.valid_split_parameters(
|
53
|
+
def split(feature_flag_name)
|
54
|
+
return unless @config.valid_mode && @splits_repository && @config.split_validator.valid_split_parameters(feature_flag_name)
|
55
55
|
|
56
56
|
if !ready?
|
57
57
|
@config.logger.error("split: the SDK is not ready, the operation cannot be executed")
|
58
58
|
return
|
59
59
|
end
|
60
60
|
|
61
|
-
|
61
|
+
sanitized_feature_flag_name = feature_flag_name.to_s.strip
|
62
62
|
|
63
|
-
if
|
64
|
-
@config.logger.warn("split:
|
65
|
-
|
63
|
+
if feature_flag_name.to_s != sanitized_feature_flag_name
|
64
|
+
@config.logger.warn("split: feature_flag_name #{feature_flag_name} has extra whitespace, trimming")
|
65
|
+
feature_flag_name = sanitized_feature_flag_name
|
66
66
|
end
|
67
67
|
|
68
|
-
split = @splits_repository.get_split(
|
68
|
+
split = @splits_repository.get_split(feature_flag_name)
|
69
69
|
|
70
70
|
if ready? && split.nil?
|
71
|
-
@config.logger.warn("split: you passed #{
|
72
|
-
'that does not exist in this environment, please double check what
|
71
|
+
@config.logger.warn("split: you passed #{feature_flag_name} " \
|
72
|
+
'that does not exist in this environment, please double check what feature flags exist in the Split user interface')
|
73
73
|
end
|
74
74
|
|
75
75
|
return if split.nil? || Engine::Models::Split.archived?(split)
|
76
76
|
|
77
|
-
build_split_view(
|
77
|
+
build_split_view(feature_flag_name, split)
|
78
78
|
end
|
79
79
|
|
80
80
|
def block_until_ready(time = nil)
|
@@ -14,7 +14,7 @@ module SplitIoClient
|
|
14
14
|
|
15
15
|
def start
|
16
16
|
if @running.value
|
17
|
-
@config.logger.debug('
|
17
|
+
@config.logger.debug('feature_flags_worker already running.')
|
18
18
|
return
|
19
19
|
end
|
20
20
|
|
@@ -24,7 +24,7 @@ module SplitIoClient
|
|
24
24
|
|
25
25
|
def stop
|
26
26
|
unless @running.value
|
27
|
-
@config.logger.debug('
|
27
|
+
@config.logger.debug('feature_flags_worker not running.')
|
28
28
|
return
|
29
29
|
end
|
30
30
|
|
@@ -33,14 +33,14 @@ module SplitIoClient
|
|
33
33
|
end
|
34
34
|
|
35
35
|
def add_to_queue(change_number)
|
36
|
-
@config.logger.debug("
|
36
|
+
@config.logger.debug("feature_flags_worker add to queue #{change_number}")
|
37
37
|
@queue.push(change_number)
|
38
38
|
end
|
39
39
|
|
40
40
|
def kill_split(change_number, split_name, default_treatment)
|
41
41
|
return if @splits_repository.get_change_number.to_i > change_number
|
42
42
|
|
43
|
-
@config.logger.debug("
|
43
|
+
@config.logger.debug("feature_flags_worker kill #{split_name}, #{change_number}")
|
44
44
|
@splits_repository.kill(change_number, split_name, default_treatment)
|
45
45
|
add_to_queue(change_number)
|
46
46
|
end
|
@@ -49,14 +49,14 @@ module SplitIoClient
|
|
49
49
|
|
50
50
|
def perform
|
51
51
|
while (change_number = @queue.pop)
|
52
|
-
@config.logger.debug("
|
52
|
+
@config.logger.debug("feature_flags_worker change_number dequeue #{change_number}")
|
53
53
|
@synchronizer.fetch_splits(change_number)
|
54
54
|
end
|
55
55
|
end
|
56
56
|
|
57
57
|
def perform_thread
|
58
58
|
@config.threads[:split_update_worker] = Thread.new do
|
59
|
-
@config.logger.debug('
|
59
|
+
@config.logger.debug('starting feature_flags_worker ...') if @config.debug_enabled
|
60
60
|
perform
|
61
61
|
end
|
62
62
|
end
|
@@ -156,7 +156,7 @@ module SplitIoClient
|
|
156
156
|
|
157
157
|
def valid_split_names?(method, split_names)
|
158
158
|
unless !split_names.nil? && split_names.is_a?(Array)
|
159
|
-
@config.logger.error("#{method}:
|
159
|
+
@config.logger.error("#{method}: feature_flag_names must be a non-empty Array")
|
160
160
|
return false
|
161
161
|
end
|
162
162
|
|
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.1.2
|
4
|
+
version: 8.1.2
|
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-05-
|
11
|
+
date: 2023-05-16 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: allocation_stats
|
@@ -562,9 +562,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
562
562
|
version: 2.5.0
|
563
563
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
564
564
|
requirements:
|
565
|
-
- - "
|
565
|
+
- - ">="
|
566
566
|
- !ruby/object:Gem::Version
|
567
|
-
version:
|
567
|
+
version: '0'
|
568
568
|
requirements: []
|
569
569
|
rubygems_version: 3.2.3
|
570
570
|
signing_key:
|