splitclient-rb 7.0.0.pre.rc3-java → 7.0.1-java

Sign up to get free protection for your applications and to get access to all the features.
Files changed (39) hide show
  1. checksums.yaml +4 -4
  2. data/.github/pull_request_template.md +10 -0
  3. data/.gitignore +2 -0
  4. data/.travis.yml +9 -0
  5. data/CHANGES.txt +18 -11
  6. data/CONTRIBUTORS-GUIDE.md +49 -0
  7. data/README.md +75 -41
  8. data/lib/splitclient-rb.rb +4 -4
  9. data/lib/splitclient-rb/cache/adapters/memory_adapters/map_adapter.rb +4 -0
  10. data/lib/splitclient-rb/cache/adapters/memory_adapters/queue_adapter.rb +4 -0
  11. data/lib/splitclient-rb/cache/repositories/impressions/memory_repository.rb +4 -0
  12. data/lib/splitclient-rb/cache/repositories/impressions_repository.rb +2 -2
  13. data/lib/splitclient-rb/cache/repositories/metrics/memory_repository.rb +1 -1
  14. data/lib/splitclient-rb/cache/repositories/metrics_repository.rb +2 -2
  15. data/lib/splitclient-rb/cache/senders/impressions_sender.rb +0 -5
  16. data/lib/splitclient-rb/cache/senders/localhost_repo_cleaner.rb +49 -0
  17. data/lib/splitclient-rb/cache/stores/localhost_split_builder.rb +94 -0
  18. data/lib/splitclient-rb/cache/stores/localhost_split_store.rb +112 -0
  19. data/lib/splitclient-rb/cache/stores/segment_store.rb +1 -7
  20. data/lib/splitclient-rb/cache/stores/split_store.rb +1 -7
  21. data/lib/splitclient-rb/cache/stores/store_utils.rb +13 -0
  22. data/lib/splitclient-rb/clients/split_client.rb +16 -13
  23. data/lib/splitclient-rb/engine/api/client.rb +6 -11
  24. data/lib/splitclient-rb/engine/api/events.rb +3 -5
  25. data/lib/splitclient-rb/engine/api/impressions.rb +1 -1
  26. data/lib/splitclient-rb/engine/parser/split_adapter.rb +18 -1
  27. data/lib/splitclient-rb/managers/split_manager.rb +10 -9
  28. data/lib/splitclient-rb/split_config.rb +79 -17
  29. data/lib/splitclient-rb/split_factory.rb +11 -4
  30. data/lib/splitclient-rb/split_factory_builder.rb +1 -21
  31. data/lib/splitclient-rb/version.rb +1 -1
  32. data/sonar-scanner.sh +42 -0
  33. metadata +11 -10
  34. data/Detailed-README.md +0 -576
  35. data/NEWS +0 -144
  36. data/lib/splitclient-rb/clients/localhost_split_client.rb +0 -184
  37. data/lib/splitclient-rb/localhost_split_factory.rb +0 -14
  38. data/lib/splitclient-rb/localhost_utils.rb +0 -59
  39. data/lib/splitclient-rb/managers/localhost_split_manager.rb +0 -60
data/NEWS DELETED
@@ -1,144 +0,0 @@
1
- 6.4.0 (Jul 05, 2019)
2
- - Added properties to track method.
3
-
4
- 6.3.0 (Apr 30, 2019)
5
-
6
- - Added Dynamic Configurations support through two new methods that mimick the regular ones, changing the type of what is returned.
7
- - get_treatment_with_config: Same as get_treatment but returning the treatment with it's config.
8
- - get_treatments_with_config: Same as get_treatments, but instead of a map of string it returns a map of treatments with config.
9
- - Added configs to SplitViews returned by the manager module.
10
- - Updated localhost mode. Now besides supporting the old text files with `.split` extension (to be deprecated soon), we support YAML (.yaml/.yml) files where you can
11
- define configurations for your treatments and also whitelisted keys. Read more in our docs!
12
-
13
- 6.2.0
14
- Ensure SDK flushes information to Split servers on client destroy
15
- Fix for compatibility issue between Faraday < 0.13 and net-http-persistent 3
16
- Change default features refresh rate interval to 5 seconds
17
-
18
- 6.1.0
19
-
20
- Review input validation for client API methods: get_treatment, get_treatments, track, manager. Add input validation to block_until_ready, client startup, and destroy
21
- Add additional logging to the SDK Client in order to help debug matcher related issues
22
- Fix for issue causing redis_url parameter to be ignored
23
-
24
- 6.0.1
25
-
26
- Fix an issue in events and impressions API calls log messages introduced in 6.0.0
27
-
28
- 6.0.0
29
-
30
- BREAKING CHANGE: Remove producer mode, make memory adapter mandatory in standalone mode, and Redis adapter mandatory in consumer mode.
31
- BREAKING CHANGE: Reduce the total number of Redis operations of the SDK by changing the impressions storage format and adding a memory cache for splits and segments. It requires to have Split Synchronizer > v2.0.0 running if you are using Redis.
32
- SDK is now compatible with net-http-persistent 3.0.
33
-
34
- 5.1.2
35
-
36
- Add input validation for client API methods: get_treatment, get_treatments, track, manager
37
-
38
- 5.1.1
39
-
40
- Reduces the number of calls to Redis when calling #client.get_treatments using such cache adapter.
41
-
42
- 5.1.0
43
-
44
- Prevent unhandled exceptions from raising when API get calls fail on Segments and Treatments.
45
-
46
- 5.0.3
47
-
48
- Creates a new configuration parameter (impressions_bulk_size) to manage the max number of impressions sent to the Split backend on each post.
49
- Changes impressions_queue_size so that it manages only the queue size in the memory adapter.
50
- A backwards compatibility fail safe is included for users of previous SDK versions.
51
-
52
- 5.0.2
53
-
54
- Turn Impression Listener into an optional SDK feature.
55
- Prevents the impression thread from being started if a listener is not in place
56
-
57
- 5.0.1
58
-
59
- Adding stop! method to the factory.
60
- With this method the user will be able to stop the threads that queries the Split Service. This will be used in the before_fork configuration in Puma and Unicorn to stop the threads in the master process.
61
-
62
- 5.0.0
63
-
64
- This is a breaking change in how users buckets are allocated.
65
- Ruby SDK was wrongly picking up the right buckets and defauled to
66
- use a "legacy hashing" instead of our moder murmur3 algo which is
67
- what other SDKs use. Please reach out to support@split.io for help
68
- on how to upgrade to this release.
69
-
70
- 4.5.0
71
-
72
- Add JRuby support
73
-
74
- 4.4.0
75
-
76
- Add the ability to send event data to split service (.track() api)
77
-
78
- 4.3.0
79
-
80
- Add support for impression listener, there is an ability to use user-defined class to capture all impressions
81
- Now you can apply attribute matcher to the traffic type
82
-
83
- 4.2.0
84
-
85
- Introduce new matchers: boolean and regexp (string).
86
- Remove unneeded dependencies
87
- Introduce dependency matcher, which allows treatment of one split to depend on the evaluation of another.
88
-
89
- 4.1.0
90
-
91
- Introduce set matchers: part of set, contains all and contains any, starts with, ends with and contains.
92
-
93
- 4.0.0
94
-
95
- Add support for murmur3 hashing algorithm
96
- Optimize gem memory usage
97
-
98
- 3.3.0
99
-
100
- Add support for traffic allocation
101
-
102
- 3.1.0
103
-
104
- Now supporting Redis as a cache adapter
105
- Factory is build now as SplitIoClient::SplitFactoryBuilder.build('<API_KEY>')
106
-
107
- 3.0.2
108
-
109
- now support also client.get_treatment( { :matching_key = 'bb' , "bucketing_key = ''}, ....)
110
-
111
- 2.0.1
112
-
113
- No news for this release
114
-
115
- 2.0.0
116
-
117
- Instantiation of the split client is now through a factory:
118
-
119
- factory = SplitIoClient::SplitFactory.new("rbk5je8be5qflpa047m17fe4ra", options)
120
- client = factory.client
121
- manager = factory.manager
122
-
123
- 1.0.4
124
-
125
- Added AND combiner for conditions support. Added events_uri config param which is the url where the metrics post are send to.
126
-
127
- 1.0.3
128
-
129
- This version of the gem fixes two minor bugs related to the config option for the refresh rates, as well as an inconsistency for the split definitions that are not created from the web app, but directly from the api instead.
130
-
131
- 1.0.2
132
-
133
- Support for all the new matchers including: number comparison with >=, <=, =, between; date comparison with is on or before, is on or after, is on, between; attribute value in a defined set of values.
134
- No other major updates for this release.
135
-
136
- 1.0.1
137
-
138
- isTreatment was removed from the API
139
- local environment file was removed to match the rest of the SDKs. "split".
140
- No other major updates for this release.
141
-
142
- 1.0.0
143
-
144
- No news for this release.
@@ -1,184 +0,0 @@
1
- module SplitIoClient
2
- class LocalhostSplitClient
3
- include SplitIoClient::LocalhostUtils
4
-
5
- #
6
- # variables to if the sdk is being used in localhost mode and store the list of features
7
- attr_reader :localhost_mode
8
- attr_reader :localhost_mode_features
9
-
10
- #
11
- # Creates a new split client instance that reads from the given splits file
12
- #
13
- # @param splits_file [File] file that contains some splits
14
- #
15
- # @return [LocalhostSplitIoClient] split.io localhost client instance
16
- def initialize(splits_file, config, reload_rate = nil)
17
- @localhost_mode = true
18
- @localhost_mode_features = []
19
- load_localhost_mode_features(splits_file, reload_rate)
20
- @config = config
21
- end
22
-
23
- #
24
- # method that returns the sdk gem version
25
- #
26
- # @return [string] version value for this sdk
27
- def self.sdk_version
28
- 'ruby-'+SplitIoClient::VERSION
29
- end
30
-
31
- #
32
- # obtains the treatments and configs for a given set of features
33
- #
34
- # @param key [string] evaluation key, only used with yaml split files
35
- # @param split_names [array] name of the features being validated
36
- # @param attributes [hash] kept for consistency with actual SDK client. Omitted in calls
37
- #
38
- # @return [hash] map of treatments (split_name, treatment)
39
- def get_treatments_with_config(key, split_names, attributes = nil)
40
- get_localhost_treatments(key, split_names, attributes, 'get_treatments_with_config')
41
- end
42
-
43
- #
44
- # obtains the treatments for a given set of features
45
- #
46
- # @param key [string] evaluation key, only used with yaml split files
47
- # @param split_names [array] name of the features being validated
48
- # @param attributes [hash] kept for consistency with actual SDK client. Omitted in calls
49
- #
50
- # @return [hash] map of treatments (split_name, treatment_name)
51
- def get_treatments(key, split_names, attributes = nil)
52
- treatments = get_localhost_treatments(key, split_names, attributes)
53
- return treatments if treatments.nil?
54
- keys = treatments.keys
55
- treats = treatments.map { |_,t| t[:treatment] }
56
- Hash[keys.zip(treats)]
57
- end
58
-
59
- #
60
- # obtains the treatment for a given feature
61
- #
62
- # @param key [string] evaluation key, only used with yaml split files
63
- # @param split_name [string] name of the feature that is being validated
64
- # @param attributes [hash] kept for consistency with actual SDK client. Omitted in calls
65
- #
66
- # @return [string] corresponding treatment
67
- def get_treatment(key, split_name, attributes = nil)
68
- get_localhost_treatment(key, split_name, attributes)[:treatment]
69
- end
70
-
71
- #
72
- # obtains the treatment and config for a given feature
73
- #
74
- # @param key [string] evaluation key, only used with yaml split files
75
- # @param split_name [string] name of the feature that is being validated
76
- # @param attributes [hash] kept for consistency with actual SDK client. Omitted in calls
77
- #
78
- # @return [hash] corresponding treatment and config
79
- def get_treatment_with_config(key, split_name, attributes = nil)
80
- get_localhost_treatment(key, split_name, attributes, 'get_treatment_with_config')
81
- end
82
-
83
- def track
84
- end
85
-
86
- private
87
-
88
- #
89
- # method to check if the sdk is running in localhost mode based on api key
90
- #
91
- # @return [boolean] True if is in localhost mode, false otherwise
92
- def is_localhost_mode?
93
- true
94
- end
95
-
96
- # @param key [string] evaluation key, only used with yaml split files
97
- # @param split_name [string] name of the feature that is being validated
98
- #
99
- # @return [Hash] corresponding treatment and config, control otherwise
100
- def get_localhost_treatment(key, split_name, attributes, calling_method = 'get_treatment')
101
- control_treatment = { label: Engine::Models::Label::EXCEPTION, treatment: SplitIoClient::Engine::Models::Treatment::CONTROL, config: nil }
102
- parsed_control_treatment = parsed_treatment(control_treatment)
103
-
104
- bucketing_key, matching_key = keys_from_key(key)
105
- return parsed_control_treatment unless @config.split_validator.valid_get_treatment_parameters(calling_method, key, split_name, matching_key, bucketing_key, attributes)
106
-
107
- sanitized_split_name = split_name.to_s.strip
108
-
109
- if split_name.to_s != sanitized_split_name
110
- @config.logger.warn("get_treatment: split_name #{split_name} has extra whitespace, trimming")
111
- split_name = sanitized_split_name
112
- end
113
-
114
- treatment = @localhost_mode_features.select { |h| h[:feature] == split_name && has_key(h[:keys], key) }.last
115
-
116
- if treatment.nil?
117
- treatment = @localhost_mode_features.select { |h| h[:feature] == split_name && h[:keys] == nil }.last
118
- end
119
-
120
- if treatment && treatment[:treatment]
121
- {
122
- treatment: treatment[:treatment],
123
- config: treatment[:config]
124
- }
125
- else
126
- parsed_control_treatment
127
- end
128
- end
129
-
130
- def get_localhost_treatments(key, split_names, attributes = nil, calling_method = 'get_treatments')
131
- return nil unless @config.split_validator.valid_get_treatments_parameters(calling_method, split_names)
132
-
133
- sanitized_split_names = sanitize_split_names(calling_method, split_names)
134
-
135
- if sanitized_split_names.empty?
136
- @config.logger.error("#{calling_method}: split_names must be a non-empty Array")
137
- return {}
138
- end
139
-
140
- split_names.each_with_object({}) do |split_name, memo|
141
- memo.merge!(split_name => get_treatment_with_config(key, split_name, attributes))
142
- end
143
- end
144
-
145
- def sanitize_split_names(calling_method, split_names)
146
- split_names.compact.uniq.select do |split_name|
147
- if (split_name.is_a?(String) || split_name.is_a?(Symbol)) && !split_name.empty?
148
- true
149
- elsif split_name.is_a?(String) && split_name.empty?
150
- @config.logger.warn("#{calling_method}: you passed an empty split_name, split_name must be a non-empty String or a Symbol")
151
- false
152
- else
153
- @config.logger.warn("#{calling_method}: you passed an invalid split_name, split_name must be a non-empty String or a Symbol")
154
- false
155
- end
156
- end
157
- end
158
-
159
- def parsed_treatment(treatment_data)
160
- {
161
- treatment: treatment_data[:treatment],
162
- config: treatment_data[:config]
163
- }
164
- end
165
-
166
- def has_key(keys, key)
167
- case keys
168
- when Array then keys.include? key
169
- when String then keys == key
170
- else
171
- false
172
- end
173
- end
174
-
175
- def keys_from_key(key)
176
- case key
177
- when Hash
178
- key.values_at(:bucketing_key, :matching_key).map { |k| k.nil? ? nil : k }
179
- else
180
- [nil, key].map { |k| k.nil? ? nil : k }
181
- end
182
- end
183
- end
184
- end
@@ -1,14 +0,0 @@
1
- module SplitIoClient
2
- class LocalhostSplitFactory
3
- attr_reader :client, :manager
4
-
5
- def initialize(splits_file, config, reload_rate = nil, logger = nil)
6
- @splits_file = splits_file
7
- @reload_rate = reload_rate
8
- @config = config
9
-
10
- @client = LocalhostSplitClient.new(@splits_file, @config, @reload_rate)
11
- @manager = LocalhostSplitManager.new(@splits_file, @reload_rate)
12
- end
13
- end
14
- end
@@ -1,59 +0,0 @@
1
- module SplitIoClient
2
- module LocalhostUtils
3
-
4
- require 'yaml'
5
- #
6
- # method to set localhost mode features by reading the given .splits
7
- #
8
- # @param splits_file [File] the .split file that contains the splits
9
- # @param reload_rate [Integer] the number of seconds to reload splits_file
10
- # @return nil
11
- def load_localhost_mode_features(splits_file, reload_rate = nil)
12
- return @localhost_mode_features unless File.exists?(splits_file)
13
-
14
- store_features(splits_file)
15
-
16
- return unless reload_rate
17
-
18
- Thread.new do
19
- loop do
20
- @localhost_mode_features = []
21
- store_features(splits_file)
22
-
23
- sleep(SplitIoClient::Utilities.randomize_interval(reload_rate))
24
- end
25
- end
26
- end
27
-
28
- def store_features(splits_file)
29
- yaml_extensions = [".yml", ".yaml"]
30
- if yaml_extensions.include? File.extname(splits_file)
31
- store_yaml_features(splits_file)
32
- else
33
- store_plain_text_features(splits_file)
34
- end
35
- end
36
-
37
- private
38
-
39
- def store_plain_text_features(splits_file)
40
- File.open(splits_file).each do |line|
41
- feature, treatment = line.strip.split(' ')
42
-
43
- next if line.start_with?('#') || line.strip.empty?
44
-
45
- @localhost_mode_features << { feature: feature, treatment: treatment, key: nil, config: nil }
46
- end
47
- end
48
-
49
- def store_yaml_features(splits_file)
50
- YAML.load(File.read(splits_file)).each do |feature|
51
- feat_symbolized_keys = feature[feature.keys.first].inject({}){|memo,(k,v)| memo[k.to_sym] = v; memo}
52
-
53
- feat_symbolized_keys[:config] = feat_symbolized_keys[:config].to_json
54
-
55
- @localhost_mode_features << { feature: feature.keys.first }.merge(feat_symbolized_keys)
56
- end
57
- end
58
- end
59
- end
@@ -1,60 +0,0 @@
1
- module SplitIoClient
2
- class LocalhostSplitManager
3
- include SplitIoClient::LocalhostUtils
4
-
5
- #
6
- # Creates a new split manager instance that holds the splits from a given file
7
- #
8
- # @param splits_file [File] the .split file that contains the splits
9
- # @param reload_rate [Integer] the number of seconds to reload splits_file
10
- #
11
- # @return [LocalhostSplitIoManager] split.io localhost manager instance
12
- def initialize(splits_file, reload_rate = nil)
13
- @localhost_mode = true
14
- @localhost_mode_features = []
15
-
16
- load_localhost_mode_features(splits_file, reload_rate)
17
- end
18
-
19
- #
20
- # method to get a split view
21
- #
22
- # @returns a split view
23
- def split(split_name)
24
- features = @localhost_mode_features.find_all { |feat| feat[:feature] == split_name }
25
-
26
- return nil if features.nil?
27
-
28
- treatments = features.map { |feat| feat[:treatment] }
29
-
30
- configs = Hash[ features.map { |feat| [ feat[:treatment].to_sym, feat[:config] ] } ]
31
-
32
- {
33
- change_number: nil,
34
- killed: false,
35
- name: split_name,
36
- traffic_type: nil,
37
- treatments: treatments,
38
- configs: configs
39
- }
40
- end
41
-
42
- #
43
- # method to get the split list from the client
44
- #
45
- # @returns Array of split view
46
- def splits
47
- split_names.map do |split_name|
48
- split(split_name)
49
- end
50
- end
51
-
52
- #
53
- # method to get the list of just split names. Ideal for ietrating and calling client.get_treatment
54
- #
55
- # @returns [object] array of split names (String)
56
- def split_names
57
- @localhost_mode_features.map{ |feat| feat[:feature]}.uniq
58
- end
59
- end
60
- end