splitclient-rb 1.0.4 → 2.0.0
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/CHANGES.txt +3 -0
- data/NEWS +8 -0
- data/README.md +29 -3
- data/lib/splitclient-engine/parser/split_adapter.rb +6 -4
- data/lib/splitclient-rb.rb +4 -1
- data/lib/splitclient-rb/localhost_split_factory.rb +169 -0
- data/lib/splitclient-rb/localhost_split_factory_builder.rb +13 -0
- data/lib/splitclient-rb/split_factory.rb +245 -0
- data/lib/splitclient-rb/split_factory_builder.rb +8 -0
- data/lib/splitclient-rb/version.rb +1 -1
- data/tasks/benchmark_get_treatment.rake +1 -1
- metadata +7 -4
- data/lib/splitclient-rb/split_client.rb +0 -156
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 420c299078bd2e0eddaeb7d2a189ab7202cb1ab9
|
4
|
+
data.tar.gz: e97bec34c8db25dcc2e3ab593b6528137b0cd505
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 01782b77e052714c779981ead8dd8e5baeae674647390dc3a89d91d00d687d16a2de2f09f8d4cd44257dc3f903537a3021cc88fb56aebfda9a52120298e0782e
|
7
|
+
data.tar.gz: 08306361a858ea57450cf182b19a52ca6c734d13038786c4edb7e25b62daff81ebb903f952370bb0e56fbd52896804fe03999a3a320215f8ed6bd57804fe5a88
|
data/CHANGES.txt
CHANGED
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
|
-
|
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::
|
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::
|
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
|
74
|
-
|
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::
|
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::
|
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
|
data/lib/splitclient-rb.rb
CHANGED
@@ -1,5 +1,8 @@
|
|
1
1
|
require 'splitclient-rb/version'
|
2
|
-
require 'splitclient-rb/
|
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
|
@@ -28,7 +28,7 @@ def execute
|
|
28
28
|
|
29
29
|
threads = []
|
30
30
|
times_per_thread = iterations / 4
|
31
|
-
split_client = SplitIoClient::
|
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:
|
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-
|
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/
|
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.
|
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
|