splitclient-rb 1.0.4 → 2.0.0

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
  SHA1:
3
- metadata.gz: 137fa6f11720e9bb8b5c55bdc1a7ce2f7ec46414
4
- data.tar.gz: b655ef282f557b2e0ef082f716f3495fe95cd4b8
3
+ metadata.gz: 420c299078bd2e0eddaeb7d2a189ab7202cb1ab9
4
+ data.tar.gz: e97bec34c8db25dcc2e3ab593b6528137b0cd505
5
5
  SHA512:
6
- metadata.gz: 349e27c839ae98fd3c8fa4829c4ed48f73711519ac97452050caa0902b4786c1c4ef8e0f82126252ad6d5fddaac63bfe64c998335eda1c6ff716e575376e8592
7
- data.tar.gz: aeacaa9bf397b6a55fc987a5f5a376632e4e9f49a81c137b11507bdd8f944b0434142b42226cb74ac73d9b52e01c62783ef85e70b9a1773d9ef803b8a8bca3d2
6
+ metadata.gz: 01782b77e052714c779981ead8dd8e5baeae674647390dc3a89d91d00d687d16a2de2f09f8d4cd44257dc3f903537a3021cc88fb56aebfda9a52120298e0782e
7
+ data.tar.gz: 08306361a858ea57450cf182b19a52ca6c734d13038786c4edb7e25b62daff81ebb903f952370bb0e56fbd52896804fe03999a3a320215f8ed6bd57804fe5a88
data/CHANGES.txt CHANGED
@@ -1,3 +1,6 @@
1
+ 2.0.0
2
+ - Add Factory for creation of Client and Manager interface.
3
+
1
4
  1.0.4
2
5
 
3
6
  - added support for AND combiner on conditions
data/NEWS CHANGED
@@ -1,3 +1,11 @@
1
+ 2.0.0
2
+
3
+ Instantiation of the split client is now through a factory:
4
+
5
+ factory = SplitIoClient::SplitFactory.new("rbk5je8be5qflpa047m17fe4ra", options)
6
+ client = factory.client
7
+ manager = factory.manager
8
+
1
9
  1.0.4
2
10
 
3
11
  Added AND combiner for conditions support. Added events_uri config param which is the url where the metrics post are send to.
data/README.md CHANGED
@@ -47,15 +47,22 @@ require 'splitclient-rb'
47
47
 
48
48
  Create a new split client instance with your API key:
49
49
  ```ruby
50
- split_client = SplitIoClient::SplitClient.new("your_api_key")
50
+ factory = SplitIoClient::SplitFactory.new("your_api_key").client
51
+ split_client = factory.client
51
52
  ```
53
+
54
+ For advance use cases you can also obtain a `manager` instance from the factory.
55
+ ```ruby
56
+ manager = factory.manager
57
+ ```
58
+
52
59
  ###Ruby on Rails
53
60
  ----
54
61
  If you're using Ruby on Rails
55
62
 
56
63
  Create an initializer file at config/initializers/splitclient.rb and then initialize the split client :
57
64
  ```ruby
58
- Rails.configuration.split_client = SplitIoClient::SplitClient.new("your_api_key")
65
+ Rails.configuration.split_client = SplitIoClient::SplitFactory.new("your_api_key").client
59
66
  ```
60
67
  In your controllers, access the client using
61
68
 
@@ -108,7 +115,7 @@ options = {base_uri: 'https://my.app.api/',
108
115
  impressions_refresh_rate: 360,
109
116
  logger: Logger.new('logfile.log')}
110
117
 
111
- split_client = SplitIoClient::SplitClient.new("your_api_key", options)
118
+ split_client = SplitIoClient::SplitFactory.new("your_api_key", options).client
112
119
  ```
113
120
  ### Execution
114
121
  ---
@@ -124,6 +131,25 @@ if split_client.get_treatment('employee_user_01','view_main_list', {age: 35})
124
131
  end
125
132
  ```
126
133
 
134
+ Also you can use the split manager:
135
+
136
+ ```ruby
137
+ split_manager = SplitIoClient::SplitFactory.new("your_api_key", options).manager
138
+ ```
139
+
140
+ With the manager you can get a list of your splits by doing:
141
+
142
+ ```ruby
143
+ manager.splits
144
+ ```
145
+
146
+ And you should get something like this:
147
+
148
+ ```bash
149
+ => [{:name=>"some_feature", :traffic_type_name=>nil, :killed=>false, :treatments=>nil, :change_number=>1469134003507}, {:name=>"another_feature", :traffic_type_name=>nil, :killed=>false, :treatments=>nil, :change_number=>1469134003414}, {:name=>"even_more_features", :traffic_type_name=>nil, :killed=>false, :treatments=>nil, :change_number=>1469133991063}, {:name=>"yet_another_feature", :traffic_type_name=>nil, :killed=>false, :treatments=>nil, :change_number=>1469133757521}]
150
+ ```
151
+
152
+
127
153
  ## Development
128
154
 
129
155
  After checking out the repo, run `bin/setup` to install dependencies. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
@@ -70,8 +70,10 @@ module SplitIoClient
70
70
  #splits fetcher
71
71
  splits_arr = []
72
72
  data = get_splits(@parsed_splits.since)
73
- data[:splits].each do |split|
74
- splits_arr << SplitIoClient::Split.new(split)
73
+ if data
74
+ data[:splits].each do |split|
75
+ splits_arr << SplitIoClient::Split.new(split)
76
+ end
75
77
  end
76
78
 
77
79
  if @parsed_splits.is_empty?
@@ -126,7 +128,7 @@ module SplitIoClient
126
128
  def call_api(path, params = {})
127
129
  @api_client.get @config.base_uri + path, params do |req|
128
130
  req.headers['Authorization'] = 'Bearer ' + @api_key
129
- req.headers['SplitSDKVersion'] = SplitIoClient::SplitClient.sdk_version
131
+ req.headers['SplitSDKVersion'] = SplitIoClient::SplitFactory.sdk_version
130
132
  req.headers['SplitSDKMachineName'] = @config.machine_name
131
133
  req.headers['SplitSDKMachineIP'] = @config.machine_ip
132
134
  req.headers['Accept-Encoding'] = 'gzip'
@@ -147,7 +149,7 @@ module SplitIoClient
147
149
  @api_client.post (@config.events_uri + path) do |req|
148
150
  req.headers['Authorization'] = 'Bearer ' + @api_key
149
151
  req.headers['Content-Type'] = 'application/json'
150
- req.headers['SplitSDKVersion'] = SplitIoClient::SplitClient.sdk_version
152
+ req.headers['SplitSDKVersion'] = SplitIoClient::SplitFactory.sdk_version
151
153
  req.headers['SplitSDKMachineName'] = @config.machine_name
152
154
  req.headers['SplitSDKMachineIP'] = @config.machine_ip
153
155
  req.body = param.to_json
@@ -1,5 +1,8 @@
1
1
  require 'splitclient-rb/version'
2
- require 'splitclient-rb/split_client'
2
+ require 'splitclient-rb/split_factory'
3
+ require 'splitclient-rb/split_factory_builder'
4
+ require 'splitclient-rb/localhost_split_factory_builder'
5
+ require 'splitclient-rb/localhost_split_factory'
3
6
  require 'splitclient-rb/split_config'
4
7
  require 'splitclient-cache/local_store'
5
8
  require 'splitclient-engine/parser/split'
@@ -0,0 +1,169 @@
1
+ require 'logger'
2
+ module SplitIoClient
3
+
4
+ #
5
+ # main class for localhost split client sdk
6
+ #
7
+ class LocalhostSplitFactory < NoMethodError
8
+ class LocalhostSplitManager < NoMethodError
9
+ #
10
+ # constant that defines the localhost mode
11
+ LOCALHOST_MODE = 'localhost'
12
+
13
+ #
14
+ # object that acts as an api adapter connector. used to get and post to api endpoints
15
+ attr_reader :adapter
16
+
17
+ #
18
+ # Creates a new split manager instance that holds the splits from a given file
19
+ #
20
+ # @param splits_file [File] the .split file that contains the splits
21
+ #
22
+ # @return [LocalhostSplitIoManager] split.io localhost manager instance
23
+ def initialize(splits_file)
24
+ @localhost_mode = true
25
+ @localhost_mode_features = []
26
+ load_localhost_mode_features(splits_file)
27
+ end
28
+
29
+ #
30
+ # method to set localhost mode features by reading the given .splits
31
+ #
32
+ # @param splits_file [File] the .split file that contains the splits
33
+ # @returns [void]
34
+ def load_localhost_mode_features(splits_file)
35
+ if File.exists?(splits_file)
36
+ line_num=0
37
+ File.open(splits_file).each do |line|
38
+ line_data = line.strip.split(" ")
39
+ @localhost_mode_features << {feature: line_data[0], treatment: line_data[1]} unless line.start_with?('#') || line.strip.empty?
40
+ end
41
+ end
42
+ @localhost_mode_features
43
+ end
44
+
45
+ #
46
+ # method to get the split list from the client
47
+ #
48
+ # @returns [object] array of splits
49
+ def splits
50
+ @localhost_mode_features
51
+ end
52
+ end
53
+
54
+ class LocalhostSplitClient < NoMethodError
55
+ #
56
+ # constant that defines the localhost mode
57
+ LOCALHOST_MODE = 'localhost'
58
+
59
+ #
60
+ # variables to if the sdk is being used in localhost mode and store the list of features
61
+ attr_reader :localhost_mode
62
+ attr_reader :localhost_mode_features
63
+
64
+ #
65
+ # Creates a new split client instance that reads from the given splits file
66
+ #
67
+ # @param splits_file [File] file that contains some splits
68
+ #
69
+ # @return [LocalhostSplitIoClient] split.io localhost client instance
70
+ def initialize(splits_file)
71
+ @localhost_mode = true
72
+ @localhost_mode_features = []
73
+ load_localhost_mode_features(splits_file)
74
+ end
75
+
76
+ #
77
+ # obtains the treatment for a given feature
78
+ #
79
+ # @param id [string] user id
80
+ # @param feature [string] name of the feature that is being validated
81
+ #
82
+ # @return [Treatment] treatment constant value
83
+ def get_treatment(id, feature, attributes = nil)
84
+ unless id
85
+ @config.logger.warn('id was null for feature: ' + feature)
86
+ return Treatments::CONTROL
87
+ end
88
+
89
+ unless feature
90
+ @config.logger.warn('feature was null for id: ' + id)
91
+ return Treatments::CONTROL
92
+ end
93
+ result = get_localhost_treatment(feature)
94
+ end
95
+
96
+
97
+ #
98
+ # auxiliary method to get the treatments avoding exceptions
99
+ #
100
+ # @param id [string] user id
101
+ # @param feature [string] name of the feature that is being validated
102
+ #
103
+ # @return [Treatment] tretment constant value
104
+ def get_treatment_without_exception_handling(id, feature, attributes = nil)
105
+ get_treatment(id, feature, attributes)
106
+ end
107
+
108
+ #
109
+ # method that returns the sdk gem version
110
+ #
111
+ # @return [string] version value for this sdk
112
+ def self.sdk_version
113
+ 'RubyClientSDK-'+SplitIoClient::VERSION
114
+ end
115
+
116
+ #
117
+ # method to check if the sdk is running in localhost mode based on api key
118
+ #
119
+ # @return [boolean] True if is in localhost mode, false otherwise
120
+ def is_localhost_mode?
121
+ true
122
+ end
123
+
124
+ #
125
+ # method to set localhost mode features by reading .splits file located at home directory
126
+ #
127
+ # @returns [void]
128
+ def load_localhost_mode_features(splits_file)
129
+ if File.exists?(splits_file)
130
+ line_num=0
131
+ File.open(splits_file).each do |line|
132
+ line_data = line.strip.split(" ")
133
+ @localhost_mode_features << {feature: line_data[0], treatment: line_data[1]} unless line.start_with?('#') || line.strip.empty?
134
+ end
135
+ end
136
+ end
137
+
138
+ #
139
+ # method to check the treatment for the given feature in localhost mode
140
+ #
141
+ # @return [boolean] true if the feature is available in localhost mode, false otherwise
142
+ def get_localhost_treatment(feature)
143
+ localhost_result = Treatments::CONTROL
144
+ treatment = @localhost_mode_features.select{|h| h[:feature] == feature}.last
145
+ localhost_result = treatment[:treatment] if !treatment.nil?
146
+ localhost_result
147
+ end
148
+
149
+ private :get_treatment_without_exception_handling, :is_localhost_mode?,
150
+ :load_localhost_mode_features, :get_localhost_treatment
151
+
152
+ end
153
+
154
+ private_constant :LocalhostSplitClient
155
+ private_constant :LocalhostSplitManager
156
+
157
+ def initialize(splits_file)
158
+ @splits_file = splits_file
159
+ end
160
+
161
+ def client
162
+ @client ||= LocalhostSplitClient.new(@splits_file)
163
+ end
164
+
165
+ def manager
166
+ @manager ||= LocalhostSplitManager.new(@splits_file)
167
+ end
168
+ end
169
+ end
@@ -0,0 +1,13 @@
1
+ module SplitIoClient
2
+ class LocalhostSplitFactoryBuilder < NoMethodError
3
+ def self.build(directory)
4
+ splits_file = File.join(directory, ".split")
5
+ LocalhostSplitFactory.new(splits_file)
6
+ end
7
+
8
+ def self.build_from_path(path)
9
+ splits_file = File.join(path)
10
+ LocalhostSplitFactory.new(splits_file)
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,245 @@
1
+ require 'logger'
2
+ module SplitIoClient
3
+ #
4
+ # main class for split client sdk
5
+ #
6
+ class SplitFactory < NoMethodError
7
+ class SplitManager < NoMethodError
8
+ #
9
+ # constant that defines the localhost mode
10
+ LOCALHOST_MODE = 'localhost'
11
+
12
+ #
13
+ # Creates a new split manager instance that connects to split.io API.
14
+ #
15
+ # @param api_key [String] the API key for your split account
16
+ #
17
+ # @return [SplitIoManager] split.io client instance
18
+ def initialize(api_key, config = {}, adapter = nil, localhost_mode = false)
19
+ @localhost_mode_features = []
20
+ @config = config
21
+ @localhost_mode = localhost_mode
22
+ if @localhost_mode
23
+ load_localhost_mode_features
24
+ else
25
+ @adapter = adapter
26
+ end
27
+ end
28
+
29
+ #
30
+ # method to set localhost mode features by reading .splits file located at home directory
31
+ #
32
+ # @returns [void]
33
+ def load_localhost_mode_features
34
+ splits_file = File.join(Dir.home, ".split")
35
+ if File.exists?(splits_file)
36
+ line_num=0
37
+ File.open(splits_file).each do |line|
38
+ line_data = line.strip.split(" ")
39
+ @localhost_mode_features << {feature: line_data[0], treatment: line_data[1]} unless line.start_with?('#') || line.strip.empty?
40
+ end
41
+ end
42
+ @localhost_mode_features
43
+ end
44
+
45
+ #
46
+ # method to get the split list from the client
47
+ #
48
+ # @returns [object] array of splits
49
+ def splits
50
+ return load_localhost_mode_features if @localhost_mode
51
+ if @adapter
52
+ @adapter.parsed_splits.splits.map do |split|
53
+ data = split.data
54
+ treatments = split.data[:conditions] && split.data[:conditions][0][:partitions] \
55
+ ? split.data[:conditions][0][:partitions].map{ |partition| partition[:treatment] }
56
+ : []
57
+ {
58
+ name: data[:name],
59
+ traffic_type_name: data[:trafficTypeName],
60
+ killed: data[:killed],
61
+ treatments: treatments,
62
+ change_number: data[:changeNumber]
63
+ }
64
+ end
65
+ else
66
+ @localhost_mode_features
67
+ end
68
+ end
69
+ end
70
+
71
+ class SplitClient < NoMethodError
72
+ #
73
+ # constant that defines the localhost mode
74
+ LOCALHOST_MODE = 'localhost'
75
+
76
+ #
77
+ # variables to if the sdk is being used in localhost mode and store the list of features
78
+ attr_reader :localhost_mode
79
+ attr_reader :localhost_mode_features
80
+
81
+ #
82
+ # Creates a new split client instance that connects to split.io API.
83
+ #
84
+ # @param api_key [String] the API key for your split account
85
+ #
86
+ # @return [SplitIoClient] split.io client instance
87
+ def initialize(api_key, config = {}, adapter = nil, localhost_mode = false)
88
+ @localhost_mode = localhost_mode
89
+ @localhost_mode_features = []
90
+
91
+ @config = config
92
+
93
+ if api_key == LOCALHOST_MODE
94
+ @localhost_mode = true
95
+ load_localhost_mode_features
96
+ else
97
+ @adapter = adapter
98
+ end
99
+ end
100
+
101
+ #
102
+ # obtains the treatment for a given feature
103
+ #
104
+ # @param id [string] user id
105
+ # @param feature [string] name of the feature that is being validated
106
+ #
107
+ # @return [Treatment] treatment constant value
108
+ def get_treatment(id, feature, attributes = nil)
109
+ unless id
110
+ @config.logger.warn('id was null for feature: ' + feature)
111
+ return Treatments::CONTROL
112
+ end
113
+
114
+ unless feature
115
+ @config.logger.warn('feature was null for id: ' + id)
116
+ return Treatments::CONTROL
117
+ end
118
+
119
+ if is_localhost_mode?
120
+ result = get_localhost_treatment(feature)
121
+ else
122
+ start = Time.now
123
+ result = nil
124
+
125
+ begin
126
+ result = get_treatment_without_exception_handling(id, feature, attributes)
127
+ rescue StandardError => error
128
+ @config.log_found_exception(__method__.to_s, error)
129
+ end
130
+
131
+ result = result.nil? ? Treatments::CONTROL : result
132
+
133
+ begin
134
+ @adapter.impressions.log(id, feature, result, (Time.now.to_f * 1000.0))
135
+ latency = (Time.now - start) * 1000.0
136
+ if (@adapter.impressions.queue.length >= @adapter.impressions.max_number_of_keys)
137
+ @adapter.impressions_producer.wakeup
138
+ end
139
+ rescue StandardError => error
140
+ @config.log_found_exception(__method__.to_s, error)
141
+ end
142
+
143
+ end
144
+
145
+ result
146
+ end
147
+
148
+ #
149
+ # auxiliary method to get the treatments avoding exceptions
150
+ #
151
+ # @param id [string] user id
152
+ # @param feature [string] name of the feature that is being validated
153
+ #
154
+ # @return [Treatment] tretment constant value
155
+ def get_treatment_without_exception_handling(id, feature, attributes = nil)
156
+ @adapter.parsed_splits.segments = @adapter.parsed_segments
157
+ split = @adapter.parsed_splits.get_split(feature)
158
+
159
+ if split.nil?
160
+ return Treatments::CONTROL
161
+ else
162
+ default_treatment = split.data[:defaultTreatment]
163
+ return @adapter.parsed_splits.get_split_treatment(id, feature, default_treatment, attributes)
164
+ end
165
+ end
166
+
167
+ #
168
+ # method that returns the sdk gem version
169
+ #
170
+ # @return [string] version value for this sdk
171
+ def self.sdk_version
172
+ 'RubyClientSDK-'+SplitIoClient::VERSION
173
+ end
174
+
175
+ #
176
+ # method to check if the sdk is running in localhost mode based on api key
177
+ #
178
+ # @return [boolean] True if is in localhost mode, false otherwise
179
+ def is_localhost_mode?
180
+ @localhost_mode
181
+ end
182
+
183
+ #
184
+ # method to set localhost mode features by reading .splits file located at home directory
185
+ #
186
+ # @returns [void]
187
+ def load_localhost_mode_features
188
+ splits_file = File.join(Dir.home, ".split")
189
+ if File.exists?(splits_file)
190
+ line_num=0
191
+ File.open(splits_file).each do |line|
192
+ line_data = line.strip.split(" ")
193
+ @localhost_mode_features << {feature: line_data[0], treatment: line_data[1]} unless line.start_with?('#') || line.strip.empty?
194
+ end
195
+ end
196
+ end
197
+
198
+ #
199
+ # method to check the treatment for the given feature in localhost mode
200
+ #
201
+ # @return [boolean] true if the feature is available in localhost mode, false otherwise
202
+ def get_localhost_treatment(feature)
203
+ localhost_result = Treatments::CONTROL
204
+ treatment = @localhost_mode_features.select{|h| h[:feature] == feature}.last
205
+ localhost_result = treatment[:treatment] if !treatment.nil?
206
+ localhost_result
207
+ end
208
+
209
+ private :get_treatment_without_exception_handling, :is_localhost_mode?,
210
+ :load_localhost_mode_features, :get_localhost_treatment
211
+
212
+ end
213
+
214
+ private_constant :SplitClient
215
+ private_constant :SplitManager
216
+
217
+ def initialize(api_key, config = {})
218
+ @api_key = api_key
219
+ @config = SplitConfig.new(config)
220
+ @adapter = api_key != 'localhost' \
221
+ ? SplitAdapter.new(api_key, @config)
222
+ : nil
223
+ @localhost_mode = api_key == 'localhost'
224
+ end
225
+
226
+ def client
227
+ @client ||= SplitClient.new(@api_key, @config, @adapter, @localhost_mode)
228
+ end
229
+
230
+ def manager
231
+ @manager ||= SplitManager.new(@api_key, @config, @adapter, @localhost_mode)
232
+ end
233
+
234
+ #
235
+ # method that returns the sdk gem version
236
+ #
237
+ # @return [string] version value for this sdk
238
+ def self.sdk_version
239
+ 'RubyClientSDK-'+SplitIoClient::VERSION
240
+ end
241
+
242
+ private
243
+ attr_reader :adapter
244
+ end
245
+ end
@@ -0,0 +1,8 @@
1
+ require 'logger'
2
+ module SplitIoClient
3
+ class SplitFactoryBuilder
4
+ def self.build(api_key, config = {})
5
+ @factory ||= SplitFactory.new(api_key, config)
6
+ end
7
+ end
8
+ end
@@ -1,3 +1,3 @@
1
1
  module SplitIoClient
2
- VERSION = '1.0.4'
2
+ VERSION = '2.0.0'
3
3
  end
@@ -28,7 +28,7 @@ def execute
28
28
 
29
29
  threads = []
30
30
  times_per_thread = iterations / 4
31
- split_client = SplitIoClient::SplitClient.new(api_key, {base_uri: base_uri, logger: Logger.new("/dev/null") })
31
+ split_client = SplitIoClient::SplitFactory.new(api_key, {base_uri: base_uri, logger: Logger.new("/dev/null").client })
32
32
 
33
33
  puts Benchmark.measure{
34
34
  4.times do |i|
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: 1.0.4
4
+ version: 2.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Split Software
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2016-06-17 00:00:00.000000000 Z
11
+ date: 2016-08-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -230,8 +230,11 @@ files:
230
230
  - lib/splitclient-engine/parser/split_parser.rb
231
231
  - lib/splitclient-engine/partitions/treatments.rb
232
232
  - lib/splitclient-rb.rb
233
- - lib/splitclient-rb/split_client.rb
233
+ - lib/splitclient-rb/localhost_split_factory.rb
234
+ - lib/splitclient-rb/localhost_split_factory_builder.rb
234
235
  - lib/splitclient-rb/split_config.rb
236
+ - lib/splitclient-rb/split_factory.rb
237
+ - lib/splitclient-rb/split_factory_builder.rb
235
238
  - lib/splitclient-rb/version.rb
236
239
  - lib/splitclient-rb_utilitites.rb
237
240
  - splitclient-rb.gemspec
@@ -258,7 +261,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
258
261
  version: '0'
259
262
  requirements: []
260
263
  rubyforge_project:
261
- rubygems_version: 2.4.8
264
+ rubygems_version: 2.5.2
262
265
  signing_key:
263
266
  specification_version: 4
264
267
  summary: Ruby client for split SDK.
@@ -1,156 +0,0 @@
1
- require 'logger'
2
-
3
- module SplitIoClient
4
-
5
- #
6
- # main class for split client sdk
7
- #
8
- class SplitClient < NoMethodError
9
-
10
- #
11
- # constant that defines the localhost mode
12
- LOCALHOST_MODE = 'localhost'
13
-
14
- #
15
- # object that acts as an api adapter connector. used to get and post to api endpoints
16
- attr_reader :adapter
17
-
18
- #
19
- # variables to if the sdk is being used in localhost mode and store the list of features
20
- attr_reader :localhost_mode
21
- attr_reader :localhost_mode_features
22
-
23
- #
24
- # Creates a new split client instance that connects to split.io API.
25
- #
26
- # @param api_key [String] the API key for your split account
27
- #
28
- # @return [SplitIoClient] split.io client instance
29
- def initialize(api_key, config = {})
30
- @localhost_mode = false
31
- @localhost_mode_features = []
32
-
33
- @config = SplitConfig.new(config)
34
-
35
- if api_key == LOCALHOST_MODE
36
- @localhost_mode = true
37
- load_localhost_mode_features
38
- else
39
- @adapter = SplitAdapter.new(api_key, @config)
40
- end
41
- end
42
-
43
- #
44
- # obtains the treatment for a given feature
45
- #
46
- # @param id [string] user id
47
- # @param feature [string] name of the feature that is being validated
48
- #
49
- # @return [Treatment] treatment constant value
50
- def get_treatment(id, feature, attributes = nil)
51
- unless id
52
- @config.logger.warn('id was null for feature: ' + feature)
53
- return Treatments::CONTROL
54
- end
55
-
56
- unless feature
57
- @config.logger.warn('feature was null for id: ' + id)
58
- return Treatments::CONTROL
59
- end
60
-
61
- if is_localhost_mode?
62
- result = get_localhost_treatment(feature)
63
- else
64
- start = Time.now
65
- result = nil
66
-
67
- begin
68
- result = get_treatment_without_exception_handling(id, feature, attributes)
69
- rescue StandardError => error
70
- @config.log_found_exception(__method__.to_s, error)
71
- end
72
-
73
- result = result.nil? ? Treatments::CONTROL : result
74
-
75
- begin
76
- @adapter.impressions.log(id, feature, result, (Time.now.to_f * 1000.0))
77
- latency = (Time.now - start) * 1000.0
78
- if (@adapter.impressions.queue.length >= @adapter.impressions.max_number_of_keys)
79
- @adapter.impressions_producer.wakeup
80
- end
81
- rescue StandardError => error
82
- @config.log_found_exception(__method__.to_s, error)
83
- end
84
-
85
- end
86
-
87
- result
88
- end
89
-
90
- #
91
- # auxiliary method to get the treatments avoding exceptions
92
- #
93
- # @param id [string] user id
94
- # @param feature [string] name of the feature that is being validated
95
- #
96
- # @return [Treatment] tretment constant value
97
- def get_treatment_without_exception_handling(id, feature, attributes = nil)
98
- @adapter.parsed_splits.segments = @adapter.parsed_segments
99
- split = @adapter.parsed_splits.get_split(feature)
100
-
101
- if split.nil?
102
- return Treatments::CONTROL
103
- else
104
- default_treatment = split.data[:defaultTreatment]
105
- return @adapter.parsed_splits.get_split_treatment(id, feature, default_treatment, attributes)
106
- end
107
- end
108
-
109
- #
110
- # method that returns the sdk gem version
111
- #
112
- # @return [string] version value for this sdk
113
- def self.sdk_version
114
- 'RubyClientSDK-'+SplitIoClient::VERSION
115
- end
116
-
117
- #
118
- # method to check if the sdk is running in localhost mode based on api key
119
- #
120
- # @return [boolean] True if is in localhost mode, false otherwise
121
- def is_localhost_mode?
122
- @localhost_mode
123
- end
124
-
125
- #
126
- # method to set localhost mode features by reading .splits file located at home directory
127
- #
128
- # @returns [void]
129
- def load_localhost_mode_features
130
- splits_file = File.join(Dir.home, ".split")
131
- if File.exists?(splits_file)
132
- line_num=0
133
- File.open(splits_file).each do |line|
134
- line_data = line.strip.split(" ")
135
- @localhost_mode_features << {feature: line_data[0], treatment: line_data[1]} unless line.start_with?('#') || line.strip.empty?
136
- end
137
- end
138
- end
139
-
140
- #
141
- # method to check the treatment for the given feature in localhost mode
142
- #
143
- # @return [boolean] true if the feature is available in localhost mode, false otherwise
144
- def get_localhost_treatment(feature)
145
- localhost_result = Treatments::CONTROL
146
- treatment = @localhost_mode_features.select{|h| h[:feature] == feature}.last
147
- localhost_result = treatment[:treatment] if !treatment.nil?
148
- localhost_result
149
- end
150
-
151
- private :get_treatment_without_exception_handling, :is_localhost_mode?,
152
- :load_localhost_mode_features, :get_localhost_treatment
153
-
154
- end
155
-
156
- end