splitclient-rb 5.0.3.pre.rc1-java → 5.1.0-java

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: 38f43edfbdd986a774f9d4667dae1a7b71a79478
4
- data.tar.gz: 20573014fb290cb7e324f975c8cffabfccde0d73
3
+ metadata.gz: 237ced7a078d2f81c4fdec42ef6ac9bb3be2ab47
4
+ data.tar.gz: 4c2ba4675ee194ba0cb1ced8725ecf1ee6dbbaf2
5
5
  SHA512:
6
- metadata.gz: 7246397145ba4e86303d1e616ff92ee2f947089ea55f05a91741bd2e80c7983662ef626273c8e8d8eac0d022a5d74701bed7efa4ade2f7562102d755dcd0acdc
7
- data.tar.gz: 553e458d7904a3319fcabc28d668fe5fae07dccd8f493bec70444e59c18be0f0b91456c032b77e643c19fc0602f377d44a568536825471ba0b0d675a86ae1bbd
6
+ metadata.gz: 5318af0f98865412ca9640dad68793ad250a7c3dd79cfeae763a89a6d8bac6e0deb8f3e1c2a7a1ca11b4297a8bc6482a1e97d7c953799530050411583b055319
7
+ data.tar.gz: 06d3f0ffce460d6e0460f6a3bc244e027cf8c30ccccd6f2ab2c495328592f75ccb1e34829b5c0d00830337d3b0ff6498a25975fdc172971ae691a47b323bf0f4
data/.rubocop.yml ADDED
@@ -0,0 +1,15 @@
1
+ Metrics/MethodLength:
2
+ Max: 15
3
+
4
+ Metrics/LineLength:
5
+ Max: 121
6
+
7
+ Metrics/BlockLength:
8
+ Exclude:
9
+ - spec/**/*
10
+ - splitclient-rb.gemspec
11
+ - exe/splitio
12
+
13
+ AllCops:
14
+ Exclude:
15
+ - lib/**/* #TODO Apply rubocop to the library
data/CHANGES.txt CHANGED
@@ -1,3 +1,10 @@
1
+ 5.1.0 (September 10th, 2018)
2
+ - Change `get_api` to return only a Faraday response.
3
+ - Add `SplitLogger` to clean up logging code and reduce the complexity in several methods.
4
+
5
+ 5.0.3 (August 13th, 2018)
6
+ - Add `impressions_bulk_size` option to set the max number of impressions to be sent to the Split backend on each post.
7
+
1
8
  5.0.2 (July 31st, 2018)
2
9
  - Prevents the impression thread from being started if a listener is not in place
3
10
 
@@ -5,7 +12,7 @@
5
12
  - Adds stop! method to the factory for gracefully stopping the SDK.
6
13
 
7
14
  5.0.0 (May 18th, 2018)
8
- - Fix bug where the sdk picked the wrong hashing algo. This is a breaking change.
15
+ - Fix bug where the sdk picked the wrong hashing algo. This is a breaking change.
9
16
 
10
17
  4.5.2 (May 16th, 2018)
11
18
  - do not return control when a split has custom attr and I don't pass attributes to get_treatment
data/Detailed-README.md CHANGED
@@ -1,216 +1,324 @@
1
1
  # Split Ruby SDK
2
2
 
3
- Ruby SDK for Split software, provided as a gem that can be installed to your Ruby application.
3
+ Ruby [Split](https://www.split.io/) SDK client.
4
4
 
5
5
  ## Installation
6
- ---
7
-
8
- - Once the gem is published you can install it with the following steps:
9
6
 
10
- Add this line to your application's Gemfile:
7
+ Install by running:
11
8
 
12
- ```ruby
13
- gem 'splitclient-rb'
14
- ```
9
+ $ gem install splitclient-rb
15
10
 
16
- And then execute:
11
+ If using [Bundler](https://bundler.io/), add this line to your `Gemfile`:
17
12
 
18
- $ bundle install
19
-
20
- Or install it yourself as:
13
+ ```ruby
14
+ gem 'splitclient-rb'
15
+ ```
21
16
 
22
- $ gem install splitclient-rb
17
+ And then run:
23
18
 
24
- - You can also use the most recent version from github:
19
+ $ bundle install
25
20
 
26
- Add these lines to you application's `Gemfile`:
27
- ```ruby
28
- gem 'splitclient-rb', git: 'https://github.com/splitio/ruby-client.git',
29
- ```
30
- You can also use any specific branch if necessary:
31
- ```ruby
32
- gem 'splitclient-rb', git: 'https://github.com/splitio/ruby-client.git', branch: 'development'
33
- ```
34
- And then execute:
21
+ Or use any specific branch by adding the following to your `Gemfile` instead:
35
22
 
36
- $ bundle install
23
+ ```ruby
24
+ gem 'splitclient-rb', git: 'https://github.com/splitio/ruby-client.git', branch: 'branch_name'
25
+ ```
37
26
 
38
27
  ## Usage
39
28
 
40
29
  ### Quick Setup
41
30
  ---
42
31
 
43
- Within your application you need the following:
44
-
45
- Require the Split client:
32
+ Within your application, include the Split client using Ruby's `require`:
46
33
  ```ruby
47
34
  require 'splitclient-rb'
48
35
  ```
49
36
 
50
- Create a new split client instance with your API key:
37
+ Then, create a new split client instance with your API key, which can be found in your Organization Settings page, in the APIs tab.
38
+
51
39
  ```ruby
52
- factory = SplitIoClient::SplitFactoryBuilder.build('YOUR_API_KEY').client
40
+ factory = SplitIoClient::SplitFactoryBuilder.build('YOUR_API_KEY')
53
41
  split_client = factory.client
54
42
  ```
55
43
 
56
- For advance use cases you can also obtain a `manager` instance from the factory.
44
+ ### Ruby on Rails
45
+ ---
46
+
47
+ Create an initializer (typically `config/initializers/split_client.rb`) with the following code:
48
+
49
+ ```ruby
50
+ Rails.configuration.split_client = SplitIoClient::SplitFactoryBuilder.build('YOUR_API_KEY').client
51
+ ```
52
+ And use the snippet below to access the client in your controllers:
53
+
57
54
  ```ruby
58
- manager = factory.manager
55
+ Rails.application.config.split_client
59
56
  ```
60
57
 
61
- #### Localhost mode
58
+ ### Using the SDK
59
+ ---
62
60
 
63
- You can run SDK in so called "localhost" mode. In this mode SDK won't hit Split API and return treatments based on ".split" file on your local machine. The format of this file is two columns separated by whitespace. The left column is the Split name, the right column is the treatment name. Here is a sample file:
61
+ In its simplest form, using the SDK is reduced to calling the `get_treatment` method of the SDK client to decide what version of your features your customers should be served for a specific feature and user. You can then use an if-else-if block for the different treatments that you defined in the Split UI:
64
62
 
63
+ ```ruby
64
+ treatment = split_client.get_treatment('user_id', 'feature_name');
65
+
66
+ if treatment == 'on'
67
+ # insert code here to show on treatment
68
+ elsif treatment == 'off'
69
+ # insert code here to show off treatment
70
+ else
71
+ # handle the client returning the control treatment
72
+ end
65
73
  ```
66
- # this is a comment
67
74
 
68
- # split_client.get_treatment('foo', 'reporting_v2') => 'on'
69
-
70
- reporting_v2 on
71
- double_writes_to_cassandra off
72
- new-navigation v3
75
+ For features that use targeting rules based on user attributes, you can call the `get_treatment` method the following way:
73
76
 
77
+ ```ruby
78
+ split_client.get_treatment('user_id','feature_name', attr: 'val')
74
79
  ```
75
80
 
76
- To use SDK in the localhost mode you should pass `localhost` as an API key like this:
81
+ e.g.
82
+ ```ruby
83
+ if split_client.get_treatment('employee_user_01','view_main_list', age: 35)
84
+ my_app.display_main_list
85
+ end
86
+ ```
77
87
 
88
+ Also, you can you can provide two different keys - one for matching and the other for bucketing:
78
89
  ```ruby
79
- factory = SplitIoClient::SplitFactoryBuilder.build('localhost', path: '/where/to-look-for/<file_name>')
80
- split_client = factory.client
90
+ split_client.get_treatment(
91
+ { matching_key: 'subscriber_id', bucketing_key: 'user_id' },
92
+ 'feature_name',
93
+ attr: 'val'
94
+ )
81
95
  ```
96
+ An scenario that requires the usage of both keys is a visitor user that browses the site and at some point gets logged into the system: as an anonymous visitor, the user browses the home page and is given the `new_homepage` treatment based on her visitor id. If the visitor signs up and turns into a subscriber, then upon being given her `subscriber_id`, Split may decide to give her the old_homepage treatment. This is of course, the opposite of the desired outcome, as the visitor's entire homepage experience would change as soon as she signs up.
82
97
 
83
- By default SDK will look in your home directory (i.e. `~`) for a `.split` file, but you can specify a different
84
- file name (full path) to look for the file (note: you must provide absolute path):
98
+ Split solves this situation by introducing the concept of a matching_key and a bucketing key. By providing the `subscriber_id` as the `matching_key` and the `visitor_id` as the `bucketing_key`, Split will give the same treatment back to the user that it used to give to the visitor.
85
99
 
86
- When in localhost mode you can make use of the SDK ability to automatically refresh splits from file, to do that just specify reload rate in seconds like this:
100
+ **Note**: read more about this topic [here](https://docs.split.io/docs/anonymous-to-logged-in).
87
101
 
102
+ The `bucketing_key` may be `nil`. In that case the `matching_key` would be used instead, so calling:
88
103
  ```ruby
89
- factory = SplitIoClient::SplitFactoryBuilder.build('localhost', path: '/where/to-look-for/<file_name>', reload_rate: 3)
104
+ split_client.get_treatment(
105
+ { matching_key: 'subscriber_id' },
106
+ 'feature_name',
107
+ attr: 'val'
108
+ )
90
109
  ```
110
+ It's exactly the same as calling:
111
+ ```ruby
112
+ split_client.get_treatment('subscriber_id' ,'feature_name', attr: 'val')
113
+ ```
114
+ **Important:** `matching_key` cannot be nil.
91
115
 
92
- ### Ruby on Rails
93
- ---
116
+ #### Split Manager
94
117
 
95
- Create an initializer: `config/initializers/splitclient.rb` and then initialize the split client:
118
+ For some advanced use cases you can use the Split Manager. To get a `manager` instance, do:
96
119
 
97
120
  ```ruby
98
- Rails.configuration.split_client = SplitIoClient::SplitFactoryBuilder.build('YOUR_API_KEY').client
121
+ split_manager = SplitIoClient::SplitFactoryBuilder.build('your_api_key', options).manager
99
122
  ```
100
- In your controllers, access the client using:
123
+ _Or simply call `#manager` in your factory instance if you built it previously._
124
+
125
+ As an example, using the manager you could get a list of your splits by doing:
101
126
 
102
127
  ```ruby
103
- Rails.application.config.split_client
128
+ split_manager.splits
104
129
  ```
105
130
 
106
- ### Configuration
107
- ---
131
+ Which would produce an output similar to:
108
132
 
109
- Split client's default configuration should be sufficient for most scenarios. However you can also provide custom configuration when initializing the client using an optional hash of options.
133
+ ```ruby
134
+ [
135
+ {
136
+ name: 'some_feature',
137
+ traffic_type_name: nil,
138
+ killed: false,
139
+ treatments: nil,
140
+ change_number: 1469134003507
141
+ },
142
+ {
143
+ name: 'another_feature',
144
+ traffic_type_name: nil,
145
+ killed: false,
146
+ treatments: nil,
147
+ change_number: 1469134003414
148
+ },
149
+ {
150
+ name: 'even_more_features',
151
+ traffic_type_name: nil,
152
+ killed: false,
153
+ treatments: nil,
154
+ change_number: 1469133991063
155
+ },
156
+ {
157
+ name: 'yet_another_feature',
158
+ traffic_type_name: nil,
159
+ killed: false,
160
+ treatments: nil,
161
+ change_number: 1469133757521
162
+ }
163
+ ]
164
+ ```
165
+
166
+ #### Localhost Mode
167
+
168
+ You can run the SDK in _localhost_ mode. In this mode, the SDK won't actually communicate with the Split API, but it'll rather return treatments based on a `.split` file on your local environment. This file must be a list of `split_name treatment_name_to_be_returned` entries. e.g.:
169
+
170
+ ```
171
+ reporting_v2 on
172
+ double_writes_to_cassandra off
173
+ new-navigation v3
174
+ ```
175
+
176
+ Using the file above, when calling:
177
+ ```ruby
178
+ split_client.get_treatment('foo', 'reporting_v2')
179
+ ```
180
+
181
+ The split client will return `on`. Note that this will be true for any bucketing or matching key.
182
+
183
+ To configure the SDK to work in localhost mode, use `localhost` as the API key:
184
+
185
+ ```ruby
186
+ factory = SplitIoClient::SplitFactoryBuilder.build('localhost', path: '/where/to-look-for/<file_name>')
187
+ split_client = factory.client
188
+ ```
189
+
190
+ By default, the SDK will look in your home directory (i.e. `~`) for the `.split` file. You can change this location by specifying an absolute path instead.
191
+
192
+ When in localhost mode, you can make use of the SDK ability to automatically refresh the splits from the `.split` file. To do that, just specify a reload rate in seconds when building the split factory instance, like this:
193
+
194
+ ```ruby
195
+ factory = SplitIoClient::SplitFactoryBuilder.build('localhost', path: '/where/to-look-for/<file_name>', reload_rate: 3)
196
+ ```
197
+
198
+ ## Advanced Configuration
199
+
200
+ Split client's default configuration should cover most scenarios. However, you can also provide custom configuration settings when initializing the factory using a hash of options. e.g.:
201
+
202
+ ```ruby
203
+ options = {
204
+ impressions_refresh_rate: 10,
205
+ debug_enabled: true,
206
+ transport_debug_enabled: false
207
+ }
208
+
209
+ factory = SplitIoClient::SplitFactoryBuilder.build('your_api_key'], options)
210
+ ```
110
211
 
111
212
  The following values can be customized:
112
213
 
113
- **base_uri** : URI for the api endpoints
214
+ **base_uri** : URI for the api endpoints.
114
215
 
115
- *defualt value* = `https://sdk.split.io/api/`
216
+ *default value* = `https://sdk.split.io/api/`
116
217
 
117
- **connection_timeout** : timeout for network connections in seconds
218
+ **connection_timeout** : Http client connection timeout (in seconds).
118
219
 
119
220
  *default value* = `5`
120
221
 
121
- **read_timeout** : timeout for requests in seconds
222
+ **read_timeout** : Http socket read timeout (in seconds).
122
223
 
123
224
  *default value* = `5`
124
225
 
125
- **features_refresh_rate** : The SDK polls Split servers for changes to feature roll-out plans. This parameter controls this polling period in seconds
126
- split_client.get_treatment('user_id','feature_name', attr: 'val')
226
+ **features_refresh_rate** : The SDK polls Split servers for changes to feature Splits every X seconds, where X is this property's value.
227
+
127
228
  *default value* = `30`
128
229
 
129
- **segments_refresh_rate** : The SDK polls Split servers for changes to segment definitions. This parameter controls this polling period in seconds
230
+ **segments_refresh_rate** : The SDK polls Split servers for changes to segments every X seconds, where X is this property's value.
130
231
 
131
232
  *default value* = `60`
132
233
 
133
- **metrics_refresh_rate** : The SDK sends diagnostic metrics to Split servers. This parameters controls this metric flush period in seconds
234
+ **metrics_refresh_rate** : The SDK sends and flushes diagnostic metrics to Split servers every X seconds where X is this property's value.
134
235
 
135
236
  *default value* = `60`
136
237
 
137
- **impressions_refresh_rate** : The SDK sends information on who got what treatment at what time back to Split servers to power analytics. This parameter controls how often this data is sent to Split servers in seconds
238
+ **impressions_refresh_rate** : The treatment log captures which customer saw what treatment ("on", "off", etc) at what time. This parameter controls how often this log is flushed back to Split servers to power analytics (in seconds).
239
+
240
+ *default value* = `60`
138
241
 
139
242
  **impressions_queue_size** : The size of the impressions queue in case of `cache_adapter == :memory`.
140
243
 
141
- **impressions_bulk_size** : Max number of impressions to be sent to the backend on each post. Defaults to `impressions_queue_size`.
244
+ *default value* = 5000
142
245
 
143
- *default value* = `60`
246
+ **impressions_bulk_size** : Maximum number of impressions to be sent to Split servers on each post.
247
+
248
+ *default value* = defaults to `impressions_queue_size`
144
249
 
145
- **debug_enabled** : Enables extra logging
250
+ **debug_enabled** : Enables extra logging (verbose mode).
146
251
 
147
252
  *default value* = `false`
148
253
 
149
- **transport_debug_enabled** : Enables extra transport logging
254
+ **transport_debug_enabled** : Super verbose mode that prints network payloads among others.
150
255
 
151
256
  *default value* = `false`
152
257
 
153
- **logger** : default logger for messages and errors
258
+ **logger** : Default logger for messages and errors.
154
259
 
155
260
  *default value* = `Logger.new($stdout)`
156
261
 
157
- **ready** : The SDK will block your app for provided amount of seconds until it's ready. If timeout expires `SplitIoClient::SDKBlockerTimeoutExpiredException` will be thrown. If `0` provided, then SDK would run in non-blocking mode
262
+ **impression_listener** : Route impressions' information to a location of your choice (in addition to the SDK servers). _See [Impression Listener](#impression-listener) section for specifics._
263
+
264
+ *default value* = (no impression listener)
265
+
266
+ **block_until_ready** : The SDK will block your app for the provided amount of seconds until it's ready. A `SplitIoClient::SDKBlockerTimeoutExpiredException` will be thrown If the provided time expires. When `0` is provided, the SDK runs in non-blocking mode.
158
267
 
159
268
  *default value* = `0`
160
269
 
161
- **labels_enabled** : Enables sending labels along with sensitive information
270
+ **labels_enabled** : Allows preventing labels from being sent to the Split servers, as they may contain sensitive information.
162
271
 
163
272
  *default value* = `true`
164
273
 
165
- **mode** : See [SDK modes section](#sdk-modes).
274
+ **mode** : See [SDK Modes](#sdk-modes).
166
275
 
167
276
  *default value* = `:standalone`
168
277
 
169
- #### Cache adapter
278
+ **cache_adapter** : Where to store data (splits, segments, and impressions) in between calls to the the Split servers. Supported options are `:memory` (default) and `:redis`.
170
279
 
171
- The SDK needs some container to store data, i.e. splits/segments/impressions. By default it will store everything in the application's memory, but you can also use Redis.
280
+ _To use Redis, include `redis-rb` in your app's Gemfile._
172
281
 
173
- To use Redis, you have to include `redis-rb` in your app's Gemfile.
282
+ *default value* = `:memory`
174
283
 
175
- **cache_adapter** : Supported options: `:memory`, `:redis`
284
+ **redis_namespace** : Prefix to add to elements in Redis cache when having to share redis with other applications.
176
285
 
177
- *default value* = `memory`
286
+ *default value* = `SPLITIO`
178
287
 
179
- **language** : SDK runner language (used in metrics/impressions Redis namespace)
288
+ **language** : SDK language (used in the Redis namespace for metrics and impressions, also included in requests' headers).
180
289
 
181
290
  *default value* = `'ruby'`
182
291
 
183
- **version** : SDK runner version (used in metrics/impressions Redis namespace)
292
+ **version** : SDK version (used in the Redis namespace for metrics and impressions, also included in requests' headers).
184
293
 
185
- *default value* = `current version of Ruby SDK`
294
+ *default value* = (current version of the SDK)
186
295
 
187
- **machine_ip** : SDK runner machine ip (used in metrics/impressions Redis namespace)
296
+ **machine_ip** : SDK machine ip (used in the Redis namespace for metrics and impressions, also included in requests' headers).
188
297
 
189
- *default value* = `current host's ip`
298
+ *default value* = (your current host's ip)
190
299
 
191
- **machine_name** : SDK runner machine name (used in metrics/impressions Redis namespace)
300
+ **machine_name** : SDK machine name (used in the Redis namespace for metrics and impressions, also included in requests' headers).
192
301
 
193
- *default value* = `current hostname`
302
+ *default value* = (your current hostname)
194
303
 
195
- **redis_url** : Redis URL or hash with configuration for SDK to connect to.
304
+ **redis_url** : Redis URL or hash with configuration for the SDK to connect to. See [Redis#initialize](https://www.rubydoc.info/github/redis/redis-rb/Redis%3Ainitialize) for detailed information.
196
305
 
197
306
  *default value* = `'redis://127.0.0.1:6379/0'`
198
307
 
199
- You can also use Sentinel like this:
308
+ _You can also use [Redis Sentinel](https://redis.io/topics/sentinel) by providing an array of sentinels in the Redis configuration:_
200
309
 
201
310
  ```ruby
202
311
  SENTINELS = [{host: '127.0.0.1', port: 26380},
203
312
  {host: '127.0.0.1', port: 26381}]
204
313
 
205
- redis_connection = { url: 'redis://mymaster', sentinels: SENTINELS, role: :master }
206
-
207
314
  options = {
208
315
  # Other options here
209
- redis_url: redis_connection
316
+ redis_url: { url: 'redis://mymaster', sentinels: SENTINELS, role: :master }
210
317
  }
211
318
  ```
319
+ ### Sample Configuration Using Redis
320
+ ---
212
321
 
213
- Example using Redis
214
322
  ```ruby
215
323
  options = {
216
324
  connection_timeout: 10,
@@ -227,150 +335,28 @@ options = {
227
335
  begin
228
336
  split_client = SplitIoClient::SplitFactoryBuilder.build('YOUR_API_KEY', options).client
229
337
  rescue SplitIoClient::SDKBlockerTimeoutExpiredException
230
- # Some arbitrary actions
231
- end
232
- ```
233
-
234
- #### Unicorn
235
-
236
- When using Unicorn without Redis (i.e. in memory mode) it's highly recommended to include the startup code above inside Unicorn's `after_fork` hook:
237
-
238
- *unicorn.rb*
239
- ```ruby
240
- # Unicorn configuration
241
- after_fork do
242
- options = {
243
- connection_timeout: 10,
244
- read_timeout: 5,
245
- features_refresh_rate: 120,
246
- segments_refresh_rate: 120,
247
- metrics_refresh_rate: 360,
248
- impressions_refresh_rate: 360,
249
- logger: Logger.new('logfile.log'),
250
- cache_adapter: :redis,
251
- mode: :standalone,
252
- redis_url: 'redis://127.0.0.1:6379/0'
253
- }
254
- begin
255
- split_client = SplitIoClient::SplitFactoryBuilder.build('YOUR_API_KEY', options).client
256
- rescue SplitIoClient::SDKBlockerTimeoutExpiredException
257
- # Some arbitrary actions
258
- end
338
+ # Code to treat raised exception
259
339
  end
260
340
  ```
261
341
 
262
- When initializing the SDK this way, SDK will only run HTTP requests from workers, not master process.
263
-
264
- #### IMPORTANT
265
-
266
- For now, SDK does not support both `producer` mode and `ready`. You must either run SDK in `standalone` mode, or do not use `ready` option.
267
-
268
- This begin-rescue-end block is optional, you might want to use it to catch timeout expired exception and apply some logic.
269
-
270
- ### Execution
342
+ ### Logging
271
343
  ---
272
344
 
273
- In your application code you just need to call the `get_treatment` method with the required parameters for key and feature name:
274
- ```ruby
275
- split_client.get_treatment('user_id','feature_name', attr: 'val')
276
- ```
277
-
278
- For example
279
- ```ruby
280
- if split_client.get_treatment('employee_user_01','view_main_list', age: 35)
281
- my_app.display_main_list
282
- end
283
- ```
345
+ By default, the SDK makes use of Ruby stdlib's `Logger` class to log errors and events. You can change the following options when configuring the SDK in your application:
284
346
 
285
- Also, you can use different keys for actually getting treatment and sending impressions to the server:
286
347
  ```ruby
287
- split_client.get_treatment(
288
- { matching_key: 'user_id', bucketing_key: 'private_user_id' },
289
- 'feature_name',
290
- attr: 'val'
291
- )
348
+ logger: Logger.new('logfile.log'), # Logger class instance.
349
+ debug_enabled: true, # Verbose logging.
350
+ transport_debug_enabled: true # Super verbose logging, including http request data.
292
351
  ```
293
- When it might be useful? Say, you have a user browsing your website and not signed up yet. You assign some internal id to that user (i.e. bucketing_key) and after user signs up you assign him a matching_key.
294
- By doing this you can provide both anonymous and signed up user with the same treatment.
295
352
 
296
- `bucketing_key` may be `nil` in that case `matching_key` would be used as a key, so calling
297
- ```ruby
298
- split_client.get_treatment(
299
- { matching_key: 'user_id' },
300
- 'feature_name',
301
- attr: 'val'
302
- )
303
- ```
304
- Is exactly the same as calling
305
- ```ruby
306
- split_client.get_treatment('user_id' ,'feature_name', attr: 'val')
307
- ```
308
- `bucketing_key` must not be nil
353
+ _Refer to [Advanced Configuration](#advanced-configuration) for more information._
309
354
 
310
- Also you can use the split manager:
311
-
312
- ```ruby
313
- split_manager = SplitIoClient::SplitFactoryBuilder.build('your_api_key', options).manager
314
- ```
315
-
316
- With the manager you can get a list of your splits by doing:
317
-
318
- ```ruby
319
- manager.splits
320
- ```
321
-
322
- And you should get something like this:
323
-
324
- ```ruby
325
- [
326
- {
327
- name: 'some_feature',
328
- traffic_type_name: nil,
329
- killed: false,
330
- treatments: nil,
331
- change_number: 1469134003507
332
- },
333
- {
334
- name: 'another_feature',
335
- traffic_type_name: nil,
336
- killed: false,
337
- treatments: nil,
338
- change_number: 1469134003414
339
- },
340
- {
341
- name: 'even_more_features',
342
- traffic_type_name: nil,
343
- killed: false,
344
- treatments: nil,
345
- change_number: 1469133991063
346
- },
347
- {
348
- name: 'yet_another_feature',
349
- traffic_type_name: nil,
350
- killed: false,
351
- treatments: nil,
352
- change_number: 1469133757521
353
- }
354
- ]
355
- ```
356
-
357
- ### Logging
358
-
359
- Ruby SDK makes use of Ruby stdlib's `Logger` class to log errors/events, default option is: `Logger.new($stdout)`.
360
-
361
- You can configure the following options in the config file:
362
-
363
- ```
364
- logger: Logger.new('logfile.log'), # you can specify your own Logger class instance here
365
- debug_enabled: true, # used for more verbose logging, including more debug information (false is the default)
366
- transport_debug_enabled: true # used for log transport data (mostly http requests, false is the default)
367
- ```
368
-
369
- ### Impression Listener
355
+ #### Impression Listener
370
356
 
371
357
  The SDK provides an optional featured called Impression Listener, that captures every single impression in your app.
372
358
 
373
- To set up an Impression Listener, define a class that implements a `log` instance method, which must receive the `impression` argument. As an example you could define your listener as follows:
359
+ To set up an Impression Listener, define a class that implements a `log` instance method, which must receive the `impression` argument. e.g.:
374
360
 
375
361
  ```ruby
376
362
  class MyImpressionListener
@@ -380,76 +366,39 @@ class MyImpressionListener
380
366
  end
381
367
  ```
382
368
 
383
- Nothing fancy here, the listener just takes an impression and logs it to the stdout. Now, to actually use this class you'll need to specify it as an option in your config (i.e. initializer) like this:
369
+ In the example above, the listener simply takes an impression and logs it to the stdout. By providing a specific listener, you could send this information to a location of your choice. To use this feature, you need to specify the class name in the corresponding option of your configuration (i.e. initializer) like this:
384
370
 
385
371
  ```ruby
386
372
  {
387
373
  # other options
388
- impression_listener: MyImpressionListener.new # do remember to initialize your class here
374
+ impression_listener: MyImpressionListener.new # remember to initialize your class here
389
375
  }
390
376
  ```
391
377
 
392
378
  ### SDK Modes
393
-
394
- By default SDK would run alongside with your application and will be run in `standalone` mode, which includes two modes:
395
- - `producer` - storing information from the Splits API in the chosen cache
396
- - `consumer` - retrieving data from the cache and providing `get_treatment` interface
397
-
398
- As you might think, you can choose between these 3 modes by providing `mode` option in the config.
399
-
400
- #### Producer mode
401
-
402
- If you have, say, one Redis cache which is used by several Split SDKs at once, e.g.: Python and Ruby, you want to have only one of them to write data to Redis, so it would remain consistent. That's why we have producer mode.
403
-
404
- SDK can be ran in `producer` mode both in the scope of the application (e.g. as a part of the Rails app), and as a separate process. Let's see what steps are needed to run it as a separate process:
405
-
406
- - You need to create a config file with .yml extension. All options specified in the above example section are valid, but you should write them in the YAML format, like this:
407
-
408
- ```yaml
409
379
  ---
410
- :api_key: 'SECRET_API_KEY'
411
- :connection_timeout: 10
412
- :read_timeout: 5
413
- :features_refresh_rate: 120
414
- :segments_refresh_rate: 120
415
- :metrics_refresh_rate: 360
416
- :impressions_refresh_rate: 360
417
- :cache_adapter: :redis
418
- :mode: :producer
419
- :redis_url: 'redis://127.0.0.1:6379/0'
420
- ```
421
380
 
381
+ The SDK is capable of running in two different modes to fit in different infrastructure configurations:
422
382
 
423
- - Install binstubs
424
- ```ruby
425
- bundle binstubs splitclient-rb
426
- ```
383
+ - `:standalone` - (default) : The SDK will retrieve information (e.g. split definitions) periodically from the Split servers, and store it in the chosen cache (memory / Redis). It'll also store the application execution information (e.g. impressions) in the cache and send it periodically to the Split servers. As it name implies, in this mode, the SDK neither relies nor synchronizes with any other component.
384
+ - `:consumer` - If using a load balancer or more than one SDK in your application, guaranteeing that all changes in split definitions are picked up by all SDK instances at the same time is highly recommended in order to ensure consistent results across your infrastructure (i.e. getting the same treatment for a specific split and user pair). To achieve this, use the [Split Synchronizer](https://docs.split.io/docs/split-synchronizer)) and setup your SDKs to work in the `consumer` mode. Setting the components this way, all communication with the Split server is orchestrated by the Synchronizer, while the SDKs pick up definitions and store the execution information from / into a shared Redis data store.
427
385
 
428
- - Run the executable provided by the SDK:
429
- ```ruby
430
- bundle exec bin/splitio -c ~/path/to/config/file.yml
431
- ```
386
+ _You can choose between these 2 modes setting the `mode` option in the config._
432
387
 
433
- Also, you can pass options directly to the cli command, like this:
434
- ```
435
- bundle exec bin/splitio -c ~/path/to/config/file.yml --debug
436
- ```
388
+ ## SDK Server Compatibility
437
389
 
438
- Note: options passed through cli have higher priority than those specified in the configuration file. To see the full list of supported options you can run:
439
- ```
440
- bundle exec bin/splitio -h
441
- ```
442
- ## Server support
443
-
444
- Currently SDK supports:
390
+ The Split Ruby SDK has been tested as a standalone app as well as using the following web servers:
445
391
  - Thin
446
392
  - Puma
447
393
  - Passenger
448
394
  - Unicorn
449
395
 
450
- Other servers should work fine as well, but haven't been tested.
396
+ For other setups, please reach out to [support@split.io](mailto:support@split.io).
397
+
398
+ ### Server Compatibility Notes
399
+ ---
451
400
 
452
- ### Unicorn and Puma in cluster mode (only for "memory mode")
401
+ #### Unicorn and Puma in cluster mode (only for "memory mode")
453
402
 
454
403
  During the start of your application, the SDK spawns multiple threads. Each thread has an infinite loop inside,
455
404
  which is used to fetch splits/segments or send impressions/metrics to the Split service continuously.
@@ -497,92 +446,76 @@ end
497
446
 
498
447
  By doing the above, the SDK will recreate the threads for each new worker and prevent the master process (that doesn't handle requests) from needlessly querying the Split service.
499
448
 
500
- ## Proxy support
449
+ ## Proxy Support
501
450
 
502
- SDK respects http_proxy environment variable, all you need to do to use proxy is assign your proxy address to that variable in the format:
451
+ SDK uses the `http_proxy` environment variable. Assign your proxy address to the variable value in the following format, and the SDK will make use of it:
503
452
 
504
453
  ```
505
454
  http_proxy=http://username:password@hostname:port
506
455
  ```
507
456
 
508
- ## Framework support
509
-
510
- Currently SDK supports:
511
- - Rails
457
+ ## Development Notes
512
458
 
513
- SDK should work with other frameworks too, but for now it has been tested only with Rails
459
+ Check out the repository and run `bin/setup` to install dependencies. You can also run `bin/console` to get an interactive prompt.
514
460
 
515
- ## Development
461
+ To install this gem onto your local machine, run `bundle exec rake install`.
516
462
 
517
- 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.
518
-
519
- To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
520
-
521
- ## Coverage
463
+ ### Tests & Coverage
464
+ ---
522
465
 
523
- The gem uses rspec for unit testing. Under the default `/spec` folder you will find the files for the unit tests and the specs helper file ( spec_helper.rb ). If a new spec file with new unit tests is required you just simply need to create it under the spec folder and all its test will be executed on the next rspec execution.
466
+ The gem uses `rspec` for unit testing. You can find the files for the unit tests and the specs helper file (`spec_helper.rb`) under the default `/spec` folder.
524
467
 
525
- To run the suite of unit tests a rake task is provided.
468
+ To run all the specs in the `spec` folder, use the provided rake task (_make sure Redis is running in localhost_):
526
469
 
527
- Make sure redis is running in localhost at redis://127.0.0.1:6379/0 and then just run:
528
470
  ```bash
529
471
  SPLITCLIENT_ENV=test bundle exec rspec spec
530
472
  ```
531
473
 
532
- Also, simplecov is used for coverage reporting. After the execution of the rake task it will create the `/coverage` folder with coverage reports in pretty HTML format.
533
- Right now, the code coverage of the gem is at about 95%.
474
+ `Simplecov` is used for coverage reporting. Upon executing the rake task it will store the reports in the `/coverage` folder.
534
475
 
535
- ## Release
536
-
537
- ```bash
538
- gem build splitclient-rb.gemspec
539
- ```
540
-
541
- This will generate a file gemspec with the right version, then:
542
-
543
- ```bash
544
- gem push splitclient-rb-<VERSION>.gem
545
- ```
546
-
547
- ## Benchmarking
476
+ ### Benchmarks
477
+ ---
548
478
 
549
- To benchmark hashing algorithms (currently we're using MurmurHash) you'll need to run:
479
+ To benchmark the hashing algorithms (MurmurHash) run:
550
480
 
551
481
  ```bash
552
482
  bundle exec rake benchmark_hashing_algorithm
553
483
  ```
554
484
 
555
- ## Contributing
485
+ ### Contribute
486
+ ---
556
487
 
557
488
  Bug reports and pull requests are welcome on GitHub at https://github.com/splitio/ruby-client.
558
489
 
559
- ## Gem version publish
490
+ ### Release
491
+ ---
492
+
493
+ To build and release a new version of the gem, document any changes into the `CHANGES.txt` and the `NEWS` files. Then, increase the version number in `version.rb`.
494
+ **Note**: This step assumes that all new features and fixes have been merged into the `development` branch, tested, validated, and finally merged into the `master` branch of the `ruby-client` repository.
560
495
 
561
- To build a new version of the gem, after you have finished the desired changes, documented the CHANGES.txt and the NEWS, as well as named it properly in the version.rb. This steps assume that all of your new cool features and fixes have been merged into development, and into master branches of the ruby-client repo. Once that is ready to go, you will have to run the build command to obtain a .gem file:
496
+ To build a new version of the gem after making the changes specified above, run:
562
497
 
563
498
  ```bash
564
499
  gem build splitclient-rb.gemspec
565
500
  ```
566
501
 
567
- That will generate a splitclient-rb-x.x.x.gem file, with the corresponding version information on it.
568
- To publish this new version of the gem at rubygems.org you must run the following command:
502
+ That will generate a `splitclient-rb-x.x.x.gem` file, with the corresponding version information on it.
503
+ To release the new version of the gem at [rubygems.org](rubygems.org) run the following command:
569
504
 
570
505
  ```bash
571
506
  gem push splitclient-rb-x.x.x.gem
572
507
  ```
573
508
 
574
- A valid rubygems username and password will be required.
509
+ _A valid rubygems username and password is required._
575
510
 
576
- After this action, the new splitclient-rb-x.x.x version is available for its use from any ruby app.
511
+ Once released, `splitclient-rb-x.x.x` version will be available for use in any ruby application.
577
512
 
578
- So for instance in a rails app Gemfile, you could add the:
513
+ To get a specific gem version in a Rails application that uses Bundler, add this line to your gemfile:
579
514
 
580
515
  ```ruby
581
516
  gem 'splitclient-rb', '~> x.x.x'
582
517
  ```
583
518
 
584
- line to have the latest version of the gem ready to be used.
585
-
586
519
  ## License
587
520
 
588
521
  The gem is available as open source under the terms of the [Apache License](http://www.apache.org/licenses/).