splitclient-rb 5.1.2.pre.rc1 → 5.1.2.pre.rc21

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a5324410589dd849f2b1d53a935d3abc47fde541973a8f3723f67cf03dcb4500
4
- data.tar.gz: 4dffe84ee479b87e4cd9f9fe0f1bf1d24eb5630ea05ffee75c0fa169cf3ac1a8
3
+ metadata.gz: d36b2f03dcee114ffe3e6bcd1ec6a1c6c4d669f716d15cf4a183c01992ce538e
4
+ data.tar.gz: 3ccd0c7f21220c57802f81a9024723b528c8e6762d3ba9075dcf9db1ae92953d
5
5
  SHA512:
6
- metadata.gz: 7c35b1fd5d27d6ede4c4df3fb00d4e48ab652c863dbf44188f8cfd06732ebd2041fca900ead703bbd91f8c8720482d15bff7ddad840d3a419c5e63f78514b95a
7
- data.tar.gz: 922d214f8135e986424fc400b759e26611da3897b1f1fdf94ecfc7eed220887294fa013b2fc412cb079b0b495ada1f9c2dd217f8ff057f0287c271cd0e056f1d
6
+ metadata.gz: 3c6f4efc722392ec4c3f8cbc7fe671cdd5c2b85dfa00fb81ca36135812da3a55092453f5d2f8608295e524f73221636be155741ac9fbd536d2e99a9a7e160044
7
+ data.tar.gz: 6e5e4ceade46af4af60b82ffdfe6c26c2f8e5432092a1cdf42d7827b3c6e40f364518ad52536e4ab988141a43575b10fb7d6cd17b85f3f574c44db4222f5ee56
data/.gitignore CHANGED
@@ -44,8 +44,5 @@ lib/murmurhash/murmurhash.so
44
44
  ext/murmurhash/murmurhash.bundle
45
45
  ext/murmurhash/murmurhash.so
46
46
 
47
- # Ignore dump.rdb
47
+ #Ignore dump.rdb
48
48
  dump.rdb
49
-
50
- # Ignore Mac OS generated files
51
- .DS_Store
data/CHANGES.txt CHANGED
@@ -1,6 +1,3 @@
1
- 5.1.2 (DATE TBD)
2
- - Add input validation for client API methods
3
-
4
1
  5.1.1 (October 4th, 2018)
5
2
  - Change get_treatments so that it sends a single latency metric
6
3
  - Removed unused call to Redis#scan when adding latencies
data/NEWS CHANGED
@@ -1,7 +1,3 @@
1
- 5.1.2
2
-
3
- Add input validation for client API methods: get_treatment, get_treatments, track, manager
4
-
5
1
  5.1.1
6
2
 
7
3
  Reduces the number of calls to Redis when calling #client.get_treatments using such cache adapter.
@@ -26,7 +26,7 @@ module SplitIoClient
26
26
 
27
27
  def get_splits(names)
28
28
  splits = {}
29
- split_names = names.map { |name| namespace_key(".split.#{name}") }
29
+ split_names = names.reject(&:empty?).uniq.map { |name| namespace_key(".split.#{name}") }
30
30
  splits.merge!(
31
31
  @adapter
32
32
  .multiple_strings(split_names)
@@ -1,5 +1,4 @@
1
1
  module SplitIoClient
2
-
3
2
  class SplitClient
4
3
  #
5
4
  # Creates a new split client instance that connects to split.io API.
@@ -18,24 +17,11 @@ module SplitIoClient
18
17
  end
19
18
 
20
19
  def get_treatments(key, split_names, attributes = {})
21
-
22
- return nil unless SplitIoClient::Validators.valid_get_treatments_parameters(split_names)
23
-
24
- sanitized_split_names = sanitize_split_names(split_names)
25
-
26
- if sanitized_split_names.empty?
27
- SplitIoClient.configuration.logger.warn('get_treatments: split_names is an empty array or has null values')
28
- return {}
29
- end
30
-
31
20
  bucketing_key, matching_key = keys_from_key(key)
32
- bucketing_key = bucketing_key ? bucketing_key.to_s : nil
33
- matching_key = matching_key ? matching_key.to_s : nil
34
-
35
21
  evaluator = Engine::Parser::Evaluator.new(@segments_repository, @splits_repository, true)
36
22
  start = Time.now
37
23
  treatments_labels_change_numbers =
38
- @splits_repository.get_splits(sanitized_split_names).each_with_object({}) do |(name, data), memo|
24
+ @splits_repository.get_splits(split_names).each_with_object({}) do |(name, data), memo|
39
25
  memo.merge!(name => get_treatment(key, name, attributes, data, false, true, evaluator))
40
26
  end
41
27
  latency = (Time.now - start) * 1000.0
@@ -48,13 +34,13 @@ module SplitIoClient
48
34
  matching_key, bucketing_key, treatments_labels_change_numbers, time
49
35
  )
50
36
 
51
- route_impressions(sanitized_split_names, matching_key, bucketing_key, time, treatments_labels_change_numbers, attributes)
37
+ route_impressions(split_names, matching_key, bucketing_key, time, treatments_labels_change_numbers, attributes)
52
38
  end
53
39
 
54
- split_names_keys = treatments_labels_change_numbers.keys
40
+ split_names = treatments_labels_change_numbers.keys
55
41
  treatments = treatments_labels_change_numbers.values.map { |v| v[:treatment] }
56
42
 
57
- Hash[split_names_keys.zip(treatments)]
43
+ Hash[split_names.zip(treatments)]
58
44
  end
59
45
 
60
46
  #
@@ -73,43 +59,68 @@ module SplitIoClient
73
59
  key, split_name, attributes = {}, split_data = nil, store_impressions = true,
74
60
  multiple = false, evaluator = nil
75
61
  )
76
- control_treatment = { label: Engine::Models::Label::EXCEPTION, treatment: SplitIoClient::Engine::Models::Treatment::CONTROL }
77
- parsed_control_treatment = parsed_treatment(multiple, control_treatment)
78
-
79
62
  bucketing_key, matching_key = keys_from_key(key)
63
+ treatment_data = { label: Engine::Models::Label::DEFINITION_NOT_FOUND, treatment: SplitIoClient::Engine::Models::Treatment::CONTROL }
64
+ evaluator ||= Engine::Parser::Evaluator.new(@segments_repository, @splits_repository)
80
65
 
81
- return parsed_control_treatment unless SplitIoClient::Validators.valid_get_treatment_parameters(key, split_name, matching_key, bucketing_key)
66
+ if matching_key.nil?
67
+ SplitIoClient.configuration.logger.warn('matching_key was null for split_name: ' + split_name.to_s)
68
+ return parsed_treatment(multiple, treatment_data)
69
+ end
82
70
 
83
- bucketing_key = bucketing_key ? bucketing_key.to_s : nil
84
- matching_key = matching_key.to_s
85
- evaluator ||= Engine::Parser::Evaluator.new(@segments_repository, @splits_repository)
71
+ if split_name.nil?
72
+ SplitIoClient.configuration.logger.warn('split_name was null for key: ' + key)
73
+ return parsed_treatment(multiple, treatment_data)
74
+ end
86
75
 
87
- begin
88
- start = Time.now
76
+ start = Time.now
89
77
 
78
+ begin
90
79
  split = multiple ? split_data : @splits_repository.get_split(split_name)
91
80
 
92
81
  if split.nil?
93
- SplitIoClient.configuration.logger.warn("split_name: #{split_name} does not exist. Returning CONTROL")
94
- return parsed_control_treatment
82
+ SplitIoClient.configuration.logger.debug("split_name: #{split_name} does not exist. Returning CONTROL")
83
+ return parsed_treatment(multiple, treatment_data)
84
+ else
85
+ treatment_data =
86
+ evaluator.call(
87
+ { bucketing_key: bucketing_key, matching_key: matching_key }, split, attributes
88
+ )
95
89
  end
90
+ rescue StandardError => error
91
+ SplitIoClient.configuration.log_found_exception(__method__.to_s, error)
96
92
 
97
- treatment_data =
98
- evaluator.call(
99
- { bucketing_key: bucketing_key, matching_key: matching_key }, split, attributes
93
+ store_impression(
94
+ split_name, matching_key, bucketing_key,
95
+ {
96
+ treatment: SplitIoClient::Engine::Models::Treatment::CONTROL,
97
+ label: SplitIoClient::Engine::Models::Label::EXCEPTION
98
+ },
99
+ store_impressions, attributes
100
100
  )
101
101
 
102
+ return parsed_treatment(multiple, treatment_data)
103
+ end
104
+
105
+ begin
102
106
  latency = (Time.now - start) * 1000.0
103
- store_impression(split_name, matching_key, bucketing_key, treatment_data, store_impressions, attributes)
107
+ split && store_impression(split_name, matching_key, bucketing_key, treatment_data, store_impressions, attributes)
104
108
 
105
109
  # Measure
106
110
  @adapter.metrics.time('sdk.get_treatment', latency) unless multiple
107
111
  rescue StandardError => error
108
112
  SplitIoClient.configuration.log_found_exception(__method__.to_s, error)
109
113
 
110
- store_impression(split_name, matching_key, bucketing_key, control_treatment, store_impressions, attributes)
114
+ store_impression(
115
+ split_name, matching_key, bucketing_key,
116
+ {
117
+ treatment: SplitIoClient::Engine::Models::Treatment::CONTROL,
118
+ label: SplitIoClient::Engine::Models::Label::EXCEPTION
119
+ },
120
+ store_impressions, attributes
121
+ )
111
122
 
112
- return parsed_control_treatment
123
+ return parsed_treatment(multiple, treatment_data)
113
124
  end
114
125
 
115
126
  parsed_treatment(multiple, treatment_data)
@@ -177,23 +188,16 @@ module SplitIoClient
177
188
  @impression_router ||= SplitIoClient::ImpressionRouter.new
178
189
  end
179
190
 
180
- def track(key, traffic_type_name, event_type, value = nil)
181
- return false unless SplitIoClient::Validators.valid_track_parameters(key, traffic_type_name, event_type, value)
182
- begin
183
- @events_repository.add(key.to_s, traffic_type_name, event_type.to_s, (Time.now.to_f * 1000).to_i, value)
184
- true
185
- rescue StandardError => error
186
- SplitIoClient.configuration.log_found_exception(__method__.to_s, error)
187
- false
188
- end
191
+ def track(key, traffic_type, event_type, value = nil)
192
+ @events_repository.add(key, traffic_type, event_type, (Time.now.to_f * 1000).to_i, value)
189
193
  end
190
194
 
191
195
  def keys_from_key(key)
192
196
  case key.class.to_s
193
197
  when 'Hash'
194
- key.values_at(:bucketing_key, :matching_key).map { |k| k.nil? ? nil : k }
198
+ key.values_at(:bucketing_key, :matching_key).map { |k| k.nil? ? nil : k.to_s }
195
199
  else
196
- [nil, key].map { |k| k.nil? ? nil : k }
200
+ [nil, key].map { |k| k.nil? ? nil : k.to_s }
197
201
  end
198
202
  end
199
203
 
@@ -208,16 +212,5 @@ module SplitIoClient
208
212
  treatment_data[:treatment]
209
213
  end
210
214
  end
211
-
212
- def sanitize_split_names(split_names)
213
- split_names.compact.uniq.select do |split_name|
214
- if split_name.is_a?(String) && !split_name.empty?
215
- true
216
- else
217
- SplitIoClient.configuration.logger.warn('get_treatments: split_name has to be a non empty string')
218
- false
219
- end
220
- end
221
- end
222
215
  end
223
216
  end
@@ -4,4 +4,5 @@ class SplitIoClient::Engine::Models::Label
4
4
  EXCEPTION = 'exception'.freeze
5
5
  KILLED = 'killed'.freeze
6
6
  NOT_IN_SPLIT = 'not in split'.freeze
7
+ DEFINITION_NOT_FOUND = 'definition not found'.freeze
7
8
  end
@@ -0,0 +1,4 @@
1
+ module SplitIoClient
2
+ class ImpressionShutdownException < StandardError
3
+ end
4
+ end
@@ -0,0 +1,4 @@
1
+ module SplitIoClient
2
+ class SDKBlockerTimeoutExpiredException < StandardError
3
+ end
4
+ end
@@ -43,7 +43,7 @@ module SplitIoClient
43
43
  #
44
44
  # @returns a split view
45
45
  def split(split_name)
46
- return unless @splits_repository && SplitIoClient::Validators.valid_split_parameters(split_name)
46
+ return unless @splits_repository
47
47
 
48
48
  split = @splits_repository.get_split(split_name)
49
49
 
@@ -63,6 +63,7 @@ module SplitIoClient
63
63
  treatments = []
64
64
  end
65
65
 
66
+
66
67
  {
67
68
  name: name,
68
69
  traffic_type_name: split[:trafficTypeName],
@@ -1,3 +1,3 @@
1
1
  module SplitIoClient
2
- VERSION = '5.1.2.pre.rc1'
2
+ VERSION = '5.1.2.pre.rc21'
3
3
  end
@@ -2,7 +2,8 @@ require 'forwardable'
2
2
 
3
3
  require 'splitclient-rb/version'
4
4
 
5
- require 'splitclient-rb/exceptions'
5
+ require 'splitclient-rb/exceptions/impressions_shutdown_exception'
6
+ require 'splitclient-rb/exceptions/sdk_blocker_timeout_expired_exception'
6
7
  require 'splitclient-rb/cache/routers/impression_router'
7
8
  require 'splitclient-rb/cache/adapters/memory_adapters/map_adapter'
8
9
  require 'splitclient-rb/cache/adapters/memory_adapters/queue_adapter'
@@ -79,7 +80,6 @@ require 'splitclient-rb/engine/models/split'
79
80
  require 'splitclient-rb/engine/models/label'
80
81
  require 'splitclient-rb/engine/models/treatment'
81
82
  require 'splitclient-rb/utilitites'
82
- require 'splitclient-rb/validators'
83
83
 
84
84
  # C extension
85
85
  require 'murmurhash/murmurhash_mri'
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: 5.1.2.pre.rc1
4
+ version: 5.1.2.pre.rc21
5
5
  platform: ruby
6
6
  authors:
7
7
  - Split Software
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2018-10-23 00:00:00.000000000 Z
11
+ date: 2018-10-18 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: allocation_stats
@@ -325,7 +325,8 @@ files:
325
325
  - lib/splitclient-rb/engine/parser/evaluator.rb
326
326
  - lib/splitclient-rb/engine/parser/partition.rb
327
327
  - lib/splitclient-rb/engine/parser/split_adapter.rb
328
- - lib/splitclient-rb/exceptions.rb
328
+ - lib/splitclient-rb/exceptions/impressions_shutdown_exception.rb
329
+ - lib/splitclient-rb/exceptions/sdk_blocker_timeout_expired_exception.rb
329
330
  - lib/splitclient-rb/localhost_split_factory.rb
330
331
  - lib/splitclient-rb/localhost_utils.rb
331
332
  - lib/splitclient-rb/managers/localhost_split_manager.rb
@@ -335,7 +336,6 @@ files:
335
336
  - lib/splitclient-rb/split_factory_builder.rb
336
337
  - lib/splitclient-rb/split_logger.rb
337
338
  - lib/splitclient-rb/utilitites.rb
338
- - lib/splitclient-rb/validators.rb
339
339
  - lib/splitclient-rb/version.rb
340
340
  - splitclient-rb.gemspec
341
341
  - splitio.yml.example
@@ -1,7 +0,0 @@
1
- module SplitIoClient
2
- class SplitIoError < StandardError; end
3
-
4
- class ImpressionShutdownException < SplitIoError; end
5
-
6
- class SDKBlockerTimeoutExpiredException < SplitIoError; end
7
- end
@@ -1,185 +0,0 @@
1
- module SplitIoClient
2
- module Validators
3
- extend self
4
-
5
- def valid_get_treatment_parameters(key, split_name, matching_key, bucketing_key)
6
- valid_key?(key) && valid_split_name?(split_name) && valid_matching_key?(matching_key) && valid_bucketing_key?(bucketing_key)
7
- end
8
-
9
- def valid_get_treatments_parameters(split_names)
10
- valid_split_names?(split_names)
11
- end
12
-
13
- def valid_track_parameters(key, traffic_type_name, event_type, value)
14
- valid_track_key?(key) && valid_traffic_type_name?(traffic_type_name) && valid_event_type?(event_type) && valid_value?(value)
15
- end
16
-
17
- def valid_split_parameters(split_name)
18
- valid_split_name?(split_name, :split)
19
- end
20
-
21
- private
22
-
23
- def string?(value)
24
- value.is_a?(String) || value.is_a?(Symbol)
25
- end
26
-
27
- def number_or_string?(value)
28
- value.is_a?(Numeric) || string?(value)
29
- end
30
-
31
- def log_nil(key, method)
32
- SplitIoClient.configuration.logger.error("#{method}: #{key} cannot be nil")
33
- end
34
-
35
- def log_string(key, method)
36
- SplitIoClient.configuration.logger.error("#{method}: #{key} must be a String or a Symbol")
37
- end
38
-
39
- def log_number_or_string(key, method)
40
- SplitIoClient.configuration.logger.error("#{method}: #{key} must be a String")
41
- end
42
-
43
- def log_convert_numeric(key, method)
44
- SplitIoClient.configuration.logger.warn("#{method}: #{key} is not of type String, converting to String")
45
- end
46
-
47
- def valid_split_name?(split_name, method=:get_treatment)
48
- if split_name.nil?
49
- log_nil(:split_name, method)
50
- return false
51
- end
52
-
53
- unless string?(split_name)
54
- log_string(:split_name, method)
55
- return false
56
- end
57
-
58
- return true
59
- end
60
-
61
- def valid_key?(key)
62
- if key.nil?
63
- log_nil(:key, :get_treatment)
64
- return false
65
- end
66
-
67
- return true
68
- end
69
-
70
- def valid_matching_key?(matching_key)
71
- if matching_key.nil?
72
- log_nil(:matching_key, :get_treatment)
73
- return false
74
- end
75
-
76
- unless number_or_string?(matching_key)
77
- log_number_or_string(:matching_key, :get_treatment)
78
- return false
79
- end
80
-
81
- if matching_key.is_a? Numeric
82
- log_convert_numeric(:matching_key, :get_treatment)
83
- end
84
-
85
- return true
86
- end
87
-
88
- def valid_bucketing_key?(bucketing_key)
89
- if bucketing_key.nil?
90
- SplitIoClient.configuration.logger.warn('get_treatment: key object should have bucketing_key set')
91
- return true
92
- end
93
-
94
- unless number_or_string?(bucketing_key)
95
- log_number_or_string(:bucketing_key, :get_treatment)
96
- return false
97
- end
98
-
99
- if bucketing_key.is_a? Numeric
100
- log_convert_numeric(:bucketing_key, :get_treatment)
101
- end
102
-
103
- return true
104
- end
105
-
106
- def valid_split_names?(split_names)
107
- if split_names.nil?
108
- log_nil(:split_names, :get_treatments)
109
- return false
110
- end
111
-
112
- unless split_names.is_a? Array
113
- SplitIoClient.configuration.logger.warn('get_treatments: split_names must be an Array')
114
- return false
115
- end
116
-
117
- return true
118
- end
119
-
120
- def valid_track_key?(key)
121
- if key.nil?
122
- log_nil(:key, :track)
123
- return false
124
- end
125
-
126
- unless number_or_string?(key)
127
- log_number_or_string(:key, :track)
128
- return false
129
- end
130
-
131
- if key.is_a? Numeric
132
- log_convert_numeric(:key, :track)
133
- end
134
-
135
- return true
136
- end
137
-
138
- def valid_event_type?(event_type)
139
- if event_type.nil?
140
- log_nil(:event_type, :track)
141
- return false
142
- end
143
-
144
- unless string?(event_type)
145
- log_string(:event_type, :track)
146
- return false
147
- end
148
-
149
- if (event_type.to_s =~ /[a-zA-Z0-9][-_\.a-zA-Z0-9]{0,62}/).nil?
150
- SplitIoClient.configuration.logger.error('track: event_type must adhere to [a-zA-Z0-9][-_\.a-zA-Z0-9]{0,62}')
151
- return false
152
- end
153
-
154
- return true
155
- end
156
-
157
- def valid_traffic_type_name?(traffic_type_name)
158
- if traffic_type_name.nil?
159
- log_nil(:traffic_type_name, :track)
160
- return false
161
- end
162
-
163
- unless string?(traffic_type_name)
164
- log_string(:traffic_type_name, :track)
165
- return false
166
- end
167
-
168
- if traffic_type_name.empty?
169
- SplitIoClient.configuration.logger.error('track: traffic_type_name must not be an empty String')
170
- return false
171
- end
172
-
173
- return true
174
- end
175
-
176
- def valid_value?(value)
177
- unless value.is_a?(Numeric) || value.nil?
178
- SplitIoClient.configuration.logger.error('track: value must be a number')
179
- return false
180
- end
181
-
182
- return true
183
- end
184
- end
185
- end