splitclient-rb 7.0.0.pre.rc3-java → 7.0.1-java
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/pull_request_template.md +10 -0
- data/.gitignore +2 -0
- data/.travis.yml +9 -0
- data/CHANGES.txt +18 -11
- data/CONTRIBUTORS-GUIDE.md +49 -0
- data/README.md +75 -41
- data/lib/splitclient-rb.rb +4 -4
- data/lib/splitclient-rb/cache/adapters/memory_adapters/map_adapter.rb +4 -0
- data/lib/splitclient-rb/cache/adapters/memory_adapters/queue_adapter.rb +4 -0
- data/lib/splitclient-rb/cache/repositories/impressions/memory_repository.rb +4 -0
- data/lib/splitclient-rb/cache/repositories/impressions_repository.rb +2 -2
- data/lib/splitclient-rb/cache/repositories/metrics/memory_repository.rb +1 -1
- data/lib/splitclient-rb/cache/repositories/metrics_repository.rb +2 -2
- data/lib/splitclient-rb/cache/senders/impressions_sender.rb +0 -5
- data/lib/splitclient-rb/cache/senders/localhost_repo_cleaner.rb +49 -0
- data/lib/splitclient-rb/cache/stores/localhost_split_builder.rb +94 -0
- data/lib/splitclient-rb/cache/stores/localhost_split_store.rb +112 -0
- data/lib/splitclient-rb/cache/stores/segment_store.rb +1 -7
- data/lib/splitclient-rb/cache/stores/split_store.rb +1 -7
- data/lib/splitclient-rb/cache/stores/store_utils.rb +13 -0
- data/lib/splitclient-rb/clients/split_client.rb +16 -13
- data/lib/splitclient-rb/engine/api/client.rb +6 -11
- data/lib/splitclient-rb/engine/api/events.rb +3 -5
- data/lib/splitclient-rb/engine/api/impressions.rb +1 -1
- data/lib/splitclient-rb/engine/parser/split_adapter.rb +18 -1
- data/lib/splitclient-rb/managers/split_manager.rb +10 -9
- data/lib/splitclient-rb/split_config.rb +79 -17
- data/lib/splitclient-rb/split_factory.rb +11 -4
- data/lib/splitclient-rb/split_factory_builder.rb +1 -21
- data/lib/splitclient-rb/version.rb +1 -1
- data/sonar-scanner.sh +42 -0
- metadata +11 -10
- data/Detailed-README.md +0 -576
- data/NEWS +0 -144
- data/lib/splitclient-rb/clients/localhost_split_client.rb +0 -184
- data/lib/splitclient-rb/localhost_split_factory.rb +0 -14
- data/lib/splitclient-rb/localhost_utils.rb +0 -59
- data/lib/splitclient-rb/managers/localhost_split_manager.rb +0 -60
@@ -38,7 +38,18 @@ module SplitIoClient
|
|
38
38
|
)
|
39
39
|
@connection_timeout = opts[:connection_timeout] || SplitConfig.default_connection_timeout
|
40
40
|
@read_timeout = opts[:read_timeout] || SplitConfig.default_read_timeout
|
41
|
-
|
41
|
+
|
42
|
+
@logger = opts[:logger] || SplitConfig.default_logger
|
43
|
+
|
44
|
+
if(opts[:reload_rate])
|
45
|
+
@features_refresh_rate = opts[:reload_rate]
|
46
|
+
@logger.warn('Localhost mode: reload_rate will be deprecated soon in favor of ' \
|
47
|
+
'features_refresh_rate. Take a look in our documentation.'
|
48
|
+
)
|
49
|
+
else
|
50
|
+
@features_refresh_rate = opts[:features_refresh_rate] || SplitConfig.default_features_refresh_rate
|
51
|
+
end
|
52
|
+
|
42
53
|
@segments_refresh_rate = opts[:segments_refresh_rate] || SplitConfig.default_segments_refresh_rate
|
43
54
|
@metrics_refresh_rate = opts[:metrics_refresh_rate] || SplitConfig.default_metrics_refresh_rate
|
44
55
|
|
@@ -48,21 +59,20 @@ module SplitIoClient
|
|
48
59
|
opts[:cache_adapter] || SplitConfig.default_cache_adapter, :queue_adapter, @impressions_queue_size, @redis_url
|
49
60
|
)
|
50
61
|
#Safeguard for users of older SDK versions.
|
51
|
-
@disable_impressions = @impressions_queue_size == -1
|
52
|
-
#Safeguard for users of older SDK versions.
|
53
62
|
@impressions_bulk_size = opts[:impressions_bulk_size] || @impressions_queue_size > 0 ? @impressions_queue_size : 0
|
54
63
|
|
55
64
|
@metrics_adapter = SplitConfig.init_cache_adapter(
|
56
65
|
opts[:cache_adapter] || SplitConfig.default_cache_adapter, :map_adapter, nil, @redis_url
|
57
66
|
)
|
58
67
|
|
59
|
-
@logger = opts[:logger] || SplitConfig.default_logger
|
60
68
|
@debug_enabled = opts[:debug_enabled] || SplitConfig.default_debug
|
61
69
|
@transport_debug_enabled = opts[:transport_debug_enabled] || SplitConfig.default_debug
|
62
70
|
@block_until_ready = SplitConfig.default_block_until_ready
|
63
71
|
|
64
|
-
@
|
65
|
-
|
72
|
+
@ip_addresses_enabled = opts[:ip_addresses_enabled].nil? ? SplitConfig.default_ip_addresses_enabled : opts[:ip_addresses_enabled]
|
73
|
+
|
74
|
+
@machine_name = SplitConfig.machine_hostname(@ip_addresses_enabled, opts[:machine_name], opts[:cache_adapter] || SplitConfig.default_cache_adapter)
|
75
|
+
@machine_ip = SplitConfig.machine_ip(@ip_addresses_enabled, opts[:machine_ip], opts[:cache_adapter] || SplitConfig.default_cache_adapter)
|
66
76
|
|
67
77
|
@cache_ttl = opts[:cache_ttl] || SplitConfig.cache_ttl
|
68
78
|
@max_cache_size = opts[:max_cache_size] || SplitConfig.max_cache_size
|
@@ -84,9 +94,14 @@ module SplitIoClient
|
|
84
94
|
@events_adapter = SplitConfig.init_cache_adapter(
|
85
95
|
opts[:cache_adapter] || SplitConfig.default_cache_adapter, :queue_adapter, @events_queue_size, @redis_url
|
86
96
|
)
|
97
|
+
|
98
|
+
@split_file = opts[:split_file] || SplitConfig.default_split_file
|
99
|
+
|
87
100
|
@valid_mode = true
|
88
101
|
@split_logger = SplitIoClient::SplitLogger.new(self)
|
89
102
|
@split_validator = SplitIoClient::Validators.new(self)
|
103
|
+
@localhost_mode = opts[:localhost_mode]
|
104
|
+
|
90
105
|
startup_log
|
91
106
|
end
|
92
107
|
|
@@ -209,12 +224,11 @@ module SplitIoClient
|
|
209
224
|
attr_accessor :impression_listener_refresh_rate
|
210
225
|
|
211
226
|
#
|
212
|
-
# How big the impressions queue is before dropping impressions
|
227
|
+
# How big the impressions queue is before dropping impressions
|
213
228
|
#
|
214
229
|
# @return [Integer]
|
215
230
|
attr_accessor :impressions_queue_size
|
216
231
|
attr_accessor :impressions_bulk_size
|
217
|
-
attr_accessor :disable_impressions
|
218
232
|
|
219
233
|
attr_accessor :redis_url
|
220
234
|
attr_accessor :redis_namespace
|
@@ -235,6 +249,12 @@ module SplitIoClient
|
|
235
249
|
# @return [Integer]
|
236
250
|
attr_accessor :events_queue_size
|
237
251
|
|
252
|
+
attr_accessor :split_file
|
253
|
+
|
254
|
+
attr_accessor :localhost_mode
|
255
|
+
|
256
|
+
attr_accessor :ip_addresses_enabled
|
257
|
+
|
238
258
|
#
|
239
259
|
# The default split client configuration
|
240
260
|
#
|
@@ -340,6 +360,14 @@ module SplitIoClient
|
|
340
360
|
500
|
341
361
|
end
|
342
362
|
|
363
|
+
def self.default_split_file
|
364
|
+
File.join(Dir.home, '.split')
|
365
|
+
end
|
366
|
+
|
367
|
+
def self.default_offline_refresh_rate
|
368
|
+
5
|
369
|
+
end
|
370
|
+
|
343
371
|
#
|
344
372
|
# The default logger object
|
345
373
|
#
|
@@ -388,6 +416,14 @@ module SplitIoClient
|
|
388
416
|
15
|
389
417
|
end
|
390
418
|
|
419
|
+
#
|
420
|
+
# The default ip addresses enabled value
|
421
|
+
#
|
422
|
+
# @return [boolean]
|
423
|
+
def self.default_ip_addresses_enabled
|
424
|
+
true
|
425
|
+
end
|
426
|
+
|
391
427
|
#
|
392
428
|
# The default transport_debug_enabled value
|
393
429
|
#
|
@@ -454,23 +490,49 @@ module SplitIoClient
|
|
454
490
|
# gets the hostname where the sdk gem is running
|
455
491
|
#
|
456
492
|
# @return [string]
|
457
|
-
def self.machine_hostname
|
458
|
-
|
459
|
-
|
460
|
-
|
493
|
+
def self.machine_hostname(ip_addresses_enabled, machine_name, adapter)
|
494
|
+
if ip_addresses_enabled
|
495
|
+
begin
|
496
|
+
return machine_name || Socket.gethostname
|
497
|
+
rescue
|
498
|
+
return 'unknown'.freeze
|
499
|
+
end
|
500
|
+
else
|
501
|
+
case adapter
|
502
|
+
when :redis
|
503
|
+
return 'NA'.freeze
|
504
|
+
end
|
505
|
+
end
|
506
|
+
|
507
|
+
return ''.freeze
|
461
508
|
end
|
462
509
|
|
463
510
|
#
|
464
511
|
# gets the ip where the sdk gem is running
|
465
512
|
#
|
466
513
|
# @return [string]
|
467
|
-
def self.machine_ip
|
468
|
-
|
469
|
-
|
514
|
+
def self.machine_ip(ip_addresses_enabled, ip, adapter)
|
515
|
+
if ip_addresses_enabled
|
516
|
+
begin
|
517
|
+
return ip unless ip.nil? || ip.to_s.empty?
|
518
|
+
|
519
|
+
loopback_ip = Socket.ip_address_list.find { |ip| ip.ipv4_loopback? }
|
520
|
+
private_ip = Socket.ip_address_list.find { |ip| ip.ipv4_private? }
|
521
|
+
|
522
|
+
addr_info = private_ip || loopback_ip
|
470
523
|
|
471
|
-
|
524
|
+
return addr_info.ip_address
|
525
|
+
rescue
|
526
|
+
return 'unknown'.freeze
|
527
|
+
end
|
528
|
+
else
|
529
|
+
case adapter
|
530
|
+
when :redis
|
531
|
+
return 'NA'.freeze
|
532
|
+
end
|
533
|
+
end
|
472
534
|
|
473
|
-
|
535
|
+
return ''.freeze
|
474
536
|
end
|
475
537
|
end
|
476
538
|
end
|
@@ -2,6 +2,8 @@ module SplitIoClient
|
|
2
2
|
class SplitFactory
|
3
3
|
ROOT_PROCESS_ID = Process.pid
|
4
4
|
SINGLETON_WARN = 'We recommend keeping only one instance of the factory at all times (Singleton pattern) and reusing it throughout your application'
|
5
|
+
LOCALHOST_API_KEY = 'localhost'
|
6
|
+
|
5
7
|
include SplitIoClient::Cache::Repositories
|
6
8
|
include SplitIoClient::Cache::Stores
|
7
9
|
|
@@ -20,10 +22,10 @@ module SplitIoClient
|
|
20
22
|
end
|
21
23
|
|
22
24
|
@api_key = api_key
|
23
|
-
@config = SplitConfig.new
|
25
|
+
@config = SplitConfig.new(config_hash.merge(localhost_mode: @api_key == LOCALHOST_API_KEY ))
|
24
26
|
|
25
27
|
raise 'Invalid SDK mode' unless valid_mode
|
26
|
-
|
28
|
+
|
27
29
|
@splits_repository = SplitsRepository.new(@config)
|
28
30
|
@segments_repository = SegmentsRepository.new(@config)
|
29
31
|
@impressions_repository = ImpressionsRepository.new(@config)
|
@@ -35,7 +37,7 @@ module SplitIoClient
|
|
35
37
|
@adapter = start!
|
36
38
|
|
37
39
|
@client = SplitClient.new(@api_key, @adapter, @splits_repository, @segments_repository, @impressions_repository, @metrics_repository, @events_repository, @sdk_blocker, @config)
|
38
|
-
@manager = SplitManager.new(@
|
40
|
+
@manager = SplitManager.new(@splits_repository, @sdk_blocker, @config)
|
39
41
|
|
40
42
|
validate_api_key
|
41
43
|
|
@@ -72,7 +74,12 @@ module SplitIoClient
|
|
72
74
|
case @config.mode
|
73
75
|
when :consumer
|
74
76
|
if @config.cache_adapter.is_a? SplitIoClient::Cache::Adapters::RedisAdapter
|
75
|
-
|
77
|
+
if !@config.localhost_mode
|
78
|
+
valid_startup_mode = true
|
79
|
+
else
|
80
|
+
@config.logger.error('Localhost mode cannot be used with Redis. ' \
|
81
|
+
'Use standalone mode and Memory adapter instead.')
|
82
|
+
end
|
76
83
|
else
|
77
84
|
@config.logger.error('Consumer mode cannot be used with Memory adapter. ' \
|
78
85
|
'Use Redis adapter instead.')
|
@@ -1,27 +1,7 @@
|
|
1
|
-
require 'logger'
|
2
|
-
|
3
1
|
module SplitIoClient
|
4
2
|
class SplitFactoryBuilder
|
5
3
|
def self.build(api_key, config = {})
|
6
|
-
|
7
|
-
when 'localhost'
|
8
|
-
configuration = SplitConfig.new(config)
|
9
|
-
LocalhostSplitFactory.new(split_file(config[:split_file], configuration.logger), configuration, config[:reload_rate])
|
10
|
-
else
|
11
|
-
SplitFactory.new(api_key, config)
|
12
|
-
end
|
13
|
-
end
|
14
|
-
|
15
|
-
private
|
16
|
-
|
17
|
-
def self.split_file(split_file_path, logger)
|
18
|
-
return split_file_path unless split_file_path.nil?
|
19
|
-
|
20
|
-
logger.warn('Localhost mode: .split mocks ' \
|
21
|
-
'will be deprecated soon in favor of YAML files, which provide more ' \
|
22
|
-
'targeting power. Take a look in our documentation.')
|
23
|
-
|
24
|
-
File.join(Dir.home, '.split')
|
4
|
+
SplitFactory.new(api_key, config)
|
25
5
|
end
|
26
6
|
end
|
27
7
|
end
|
data/sonar-scanner.sh
ADDED
@@ -0,0 +1,42 @@
|
|
1
|
+
#/bin/bash -e
|
2
|
+
|
3
|
+
sonar_scanner() {
|
4
|
+
local params=$@
|
5
|
+
|
6
|
+
sonar-scanner \
|
7
|
+
-Dsonar.host.url='https://sonarqube.split-internal.com' \
|
8
|
+
-Dsonar.login="$SONAR_TOKEN" \
|
9
|
+
-Dsonar.ws.timeout='300' \
|
10
|
+
-Dsonar.sources='lib' \
|
11
|
+
-Dsonar.projectName='ruby-client' \
|
12
|
+
-Dsonar.projectKey='ruby-client' \
|
13
|
+
-Dsonar.ruby.coverage.reportPaths='coverage/.resultset.json' \
|
14
|
+
-Dsonar.links.ci='https://travis-ci.com/splitio/ruby-client' \
|
15
|
+
-Dsonar.links.scm='https://github.com/splitio/ruby-client' \
|
16
|
+
${params}
|
17
|
+
|
18
|
+
return $?
|
19
|
+
}
|
20
|
+
|
21
|
+
if [ "$TRAVIS_PULL_REQUEST" != "false" ]; then
|
22
|
+
sonar_scanner \
|
23
|
+
-Dsonar.pullrequest.provider='GitHub' \
|
24
|
+
-Dsonar.pullrequest.github.repository='splitio/ruby-client' \
|
25
|
+
-Dsonar.pullrequest.key=$TRAVIS_PULL_REQUEST \
|
26
|
+
-Dsonar.pullrequest.branch=$TRAVIS_PULL_REQUEST_BRANCH \
|
27
|
+
-Dsonar.pullrequest.base=$TRAVIS_BRANCH
|
28
|
+
else
|
29
|
+
if [ "$TRAVIS_BRANCH" == 'master' ]; then
|
30
|
+
sonar_scanner \
|
31
|
+
-Dsonar.branch.name=$TRAVIS_BRANCH
|
32
|
+
else
|
33
|
+
if [ "$TRAVIS_BRANCH" == 'development' ]; then
|
34
|
+
TARGET_BRANCH='master'
|
35
|
+
else
|
36
|
+
TARGET_BRANCH='development'
|
37
|
+
fi
|
38
|
+
sonar_scanner \
|
39
|
+
-Dsonar.branch.name=$TRAVIS_BRANCH \
|
40
|
+
-Dsonar.branch.target=$TARGET_BRANCH
|
41
|
+
fi
|
42
|
+
fi
|
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: 7.0.
|
4
|
+
version: 7.0.1
|
5
5
|
platform: java
|
6
6
|
authors:
|
7
7
|
- Split Software
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2019-
|
11
|
+
date: 2019-11-13 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
requirement: !ruby/object:Gem::Requirement
|
@@ -283,16 +283,16 @@ executables: []
|
|
283
283
|
extensions: []
|
284
284
|
extra_rdoc_files: []
|
285
285
|
files:
|
286
|
+
- ".github/pull_request_template.md"
|
286
287
|
- ".gitignore"
|
287
288
|
- ".rubocop.yml"
|
288
289
|
- ".simplecov"
|
289
290
|
- ".travis.yml"
|
290
291
|
- Appraisals
|
291
292
|
- CHANGES.txt
|
292
|
-
-
|
293
|
+
- CONTRIBUTORS-GUIDE.md
|
293
294
|
- Gemfile
|
294
295
|
- LICENSE
|
295
|
-
- NEWS
|
296
296
|
- README.md
|
297
297
|
- Rakefile
|
298
298
|
- ext/murmurhash/MurmurHash3.java
|
@@ -323,11 +323,14 @@ files:
|
|
323
323
|
- lib/splitclient-rb/cache/senders/events_sender.rb
|
324
324
|
- lib/splitclient-rb/cache/senders/impressions_formatter.rb
|
325
325
|
- lib/splitclient-rb/cache/senders/impressions_sender.rb
|
326
|
+
- lib/splitclient-rb/cache/senders/localhost_repo_cleaner.rb
|
326
327
|
- lib/splitclient-rb/cache/senders/metrics_sender.rb
|
328
|
+
- lib/splitclient-rb/cache/stores/localhost_split_builder.rb
|
329
|
+
- lib/splitclient-rb/cache/stores/localhost_split_store.rb
|
327
330
|
- lib/splitclient-rb/cache/stores/sdk_blocker.rb
|
328
331
|
- lib/splitclient-rb/cache/stores/segment_store.rb
|
329
332
|
- lib/splitclient-rb/cache/stores/split_store.rb
|
330
|
-
- lib/splitclient-rb/
|
333
|
+
- lib/splitclient-rb/cache/stores/store_utils.rb
|
331
334
|
- lib/splitclient-rb/clients/split_client.rb
|
332
335
|
- lib/splitclient-rb/engine/api/client.rb
|
333
336
|
- lib/splitclient-rb/engine/api/events.rb
|
@@ -370,9 +373,6 @@ files:
|
|
370
373
|
- lib/splitclient-rb/engine/parser/partition.rb
|
371
374
|
- lib/splitclient-rb/engine/parser/split_adapter.rb
|
372
375
|
- lib/splitclient-rb/exceptions.rb
|
373
|
-
- lib/splitclient-rb/localhost_split_factory.rb
|
374
|
-
- lib/splitclient-rb/localhost_utils.rb
|
375
|
-
- lib/splitclient-rb/managers/localhost_split_manager.rb
|
376
376
|
- lib/splitclient-rb/managers/split_manager.rb
|
377
377
|
- lib/splitclient-rb/redis_metrics_fixer.rb
|
378
378
|
- lib/splitclient-rb/split_config.rb
|
@@ -383,6 +383,7 @@ files:
|
|
383
383
|
- lib/splitclient-rb/utilitites.rb
|
384
384
|
- lib/splitclient-rb/validators.rb
|
385
385
|
- lib/splitclient-rb/version.rb
|
386
|
+
- sonar-scanner.sh
|
386
387
|
- splitclient-rb.gemspec
|
387
388
|
- tasks/benchmark_get_treatment.rake
|
388
389
|
- tasks/irb.rake
|
@@ -401,9 +402,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
401
402
|
version: '0'
|
402
403
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
403
404
|
requirements:
|
404
|
-
- - "
|
405
|
+
- - ">="
|
405
406
|
- !ruby/object:Gem::Version
|
406
|
-
version:
|
407
|
+
version: '0'
|
407
408
|
requirements: []
|
408
409
|
rubyforge_project:
|
409
410
|
rubygems_version: 2.6.14
|
data/Detailed-README.md
DELETED
@@ -1,576 +0,0 @@
|
|
1
|
-
# Split Ruby SDK
|
2
|
-
|
3
|
-
Ruby [Split](https://www.split.io/) SDK client.
|
4
|
-
|
5
|
-
## Installation
|
6
|
-
|
7
|
-
Install by running:
|
8
|
-
|
9
|
-
$ gem install splitclient-rb
|
10
|
-
|
11
|
-
If using [Bundler](https://bundler.io/), add this line to your `Gemfile`:
|
12
|
-
|
13
|
-
```ruby
|
14
|
-
gem 'splitclient-rb'
|
15
|
-
```
|
16
|
-
|
17
|
-
And then run:
|
18
|
-
|
19
|
-
$ bundle install
|
20
|
-
|
21
|
-
Or use any specific branch by adding the following to your `Gemfile` instead:
|
22
|
-
|
23
|
-
```ruby
|
24
|
-
gem 'splitclient-rb', git: 'https://github.com/splitio/ruby-client.git', branch: 'branch_name'
|
25
|
-
```
|
26
|
-
|
27
|
-
## Usage
|
28
|
-
|
29
|
-
### Quick Setup
|
30
|
-
---
|
31
|
-
|
32
|
-
Within your application, include the Split client using Ruby's `require`:
|
33
|
-
```ruby
|
34
|
-
require 'splitclient-rb'
|
35
|
-
```
|
36
|
-
|
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
|
-
|
39
|
-
```ruby
|
40
|
-
factory = SplitIoClient::SplitFactoryBuilder.build('YOUR_API_KEY')
|
41
|
-
split_client = factory.client
|
42
|
-
```
|
43
|
-
|
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
|
-
|
54
|
-
```ruby
|
55
|
-
Rails.application.config.split_client
|
56
|
-
```
|
57
|
-
|
58
|
-
### Using the SDK
|
59
|
-
---
|
60
|
-
|
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:
|
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
|
73
|
-
```
|
74
|
-
|
75
|
-
**Note**: You can ensure the SDK resources are loaded before querying for treatments by using `block_until_ready`.
|
76
|
-
|
77
|
-
``` ruby
|
78
|
-
factory = SplitIoClient::SplitFactoryBuilder.build('YOUR_API_KEY')
|
79
|
-
split_client = factory.client
|
80
|
-
split_client.block_until_ready # Wait for a specified time (default 15 seconds). SDK raises an SDKBlockerTimeoutExpiredException if not ready by then
|
81
|
-
```
|
82
|
-
|
83
|
-
For features that use targeting rules based on user attributes, you can call the `get_treatment` method the following way:
|
84
|
-
|
85
|
-
```ruby
|
86
|
-
split_client.get_treatment('user_id','feature_name', attr: 'val')
|
87
|
-
```
|
88
|
-
|
89
|
-
e.g.
|
90
|
-
```ruby
|
91
|
-
if split_client.get_treatment('employee_user_01','view_main_list', age: 35)
|
92
|
-
my_app.display_main_list
|
93
|
-
end
|
94
|
-
```
|
95
|
-
|
96
|
-
Also, you can you can provide two different keys - one for matching and the other for bucketing:
|
97
|
-
```ruby
|
98
|
-
split_client.get_treatment(
|
99
|
-
{ matching_key: 'subscriber_id', bucketing_key: 'user_id' },
|
100
|
-
'feature_name',
|
101
|
-
attr: 'val'
|
102
|
-
)
|
103
|
-
```
|
104
|
-
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.
|
105
|
-
|
106
|
-
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.
|
107
|
-
|
108
|
-
The `bucketing_key` may be `nil`. In that case the `matching_key` would be used instead, so calling:
|
109
|
-
```ruby
|
110
|
-
split_client.get_treatment(
|
111
|
-
{ matching_key: 'subscriber_id' },
|
112
|
-
'feature_name',
|
113
|
-
attr: 'val'
|
114
|
-
)
|
115
|
-
```
|
116
|
-
It's exactly the same as calling:
|
117
|
-
```ruby
|
118
|
-
split_client.get_treatment('subscriber_id' ,'feature_name', attr: 'val')
|
119
|
-
```
|
120
|
-
**Important:** `matching_key` cannot be nil.
|
121
|
-
|
122
|
-
#### Split Manager
|
123
|
-
|
124
|
-
For some advanced use cases you can use the Split Manager. To get a `manager` instance, do:
|
125
|
-
|
126
|
-
```ruby
|
127
|
-
split_manager = SplitIoClient::SplitFactoryBuilder.build('your_api_key', options).manager
|
128
|
-
```
|
129
|
-
_Or simply call `#manager` in your factory instance if you built it previously._
|
130
|
-
|
131
|
-
As an example, using the manager you could get a list of your splits by doing:
|
132
|
-
|
133
|
-
```ruby
|
134
|
-
split_manager.splits
|
135
|
-
```
|
136
|
-
|
137
|
-
Which would produce an output similar to:
|
138
|
-
|
139
|
-
```ruby
|
140
|
-
[
|
141
|
-
{
|
142
|
-
name: 'some_feature',
|
143
|
-
traffic_type_name: nil,
|
144
|
-
killed: false,
|
145
|
-
treatments: nil,
|
146
|
-
change_number: 1469134003507
|
147
|
-
},
|
148
|
-
{
|
149
|
-
name: 'another_feature',
|
150
|
-
traffic_type_name: nil,
|
151
|
-
killed: false,
|
152
|
-
treatments: nil,
|
153
|
-
change_number: 1469134003414
|
154
|
-
},
|
155
|
-
{
|
156
|
-
name: 'even_more_features',
|
157
|
-
traffic_type_name: nil,
|
158
|
-
killed: false,
|
159
|
-
treatments: nil,
|
160
|
-
change_number: 1469133991063
|
161
|
-
},
|
162
|
-
{
|
163
|
-
name: 'yet_another_feature',
|
164
|
-
traffic_type_name: nil,
|
165
|
-
killed: false,
|
166
|
-
treatments: nil,
|
167
|
-
change_number: 1469133757521
|
168
|
-
}
|
169
|
-
]
|
170
|
-
```
|
171
|
-
|
172
|
-
**Note**: `block_until_ready` is also available as a Split manager method
|
173
|
-
|
174
|
-
#### Localhost Mode
|
175
|
-
|
176
|
-
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.:
|
177
|
-
|
178
|
-
```
|
179
|
-
reporting_v2 on
|
180
|
-
double_writes_to_cassandra off
|
181
|
-
new-navigation v3
|
182
|
-
```
|
183
|
-
|
184
|
-
Using the file above, when calling:
|
185
|
-
```ruby
|
186
|
-
split_client.get_treatment('foo', 'reporting_v2')
|
187
|
-
```
|
188
|
-
|
189
|
-
The split client will return `on`. Note that this will be true for any bucketing or matching key.
|
190
|
-
|
191
|
-
To configure the SDK to work in localhost mode, use `localhost` as the API key:
|
192
|
-
|
193
|
-
```ruby
|
194
|
-
factory = SplitIoClient::SplitFactoryBuilder.build('localhost', path: '/where/to-look-for/<file_name>')
|
195
|
-
split_client = factory.client
|
196
|
-
```
|
197
|
-
|
198
|
-
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.
|
199
|
-
|
200
|
-
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:
|
201
|
-
|
202
|
-
```ruby
|
203
|
-
factory = SplitIoClient::SplitFactoryBuilder.build('localhost', path: '/where/to-look-for/<file_name>', reload_rate: 3)
|
204
|
-
```
|
205
|
-
|
206
|
-
### SDK Input Validations
|
207
|
-
|
208
|
-
In order to provide consistency among the SDKs for the different programming languages, provide better output to users in case of errors, and prevent unexpected errors to raise exceptions in your application, most of the parameters in the SDK methods are validated against a set of rules. Similarly, some of the configuration parameters must follow these rules, too. Check your application against the list below to prevent issues when using the SDK.
|
209
|
-
|
210
|
-
#### get_treatment (split_client)
|
211
|
-
|
212
|
-
- `key` (when not using matching_key and bucketing_key): must be a non-empty `String` or a `Symbol`, shorter than 250 characters. If a non-NaN `Numeric` value is used, it'll be converted to its `String` representation.
|
213
|
-
|
214
|
-
- `matching_key`, `bucketing_key`: the containing `Hash` must have both keys, and the same rules above apply for each.
|
215
|
-
|
216
|
-
- `split_name`: must be a non-empty `String` or a `Symbol`. Whitespaces will be trimmed from both ends of it. The trimmed version of the `split_name` will be used for both evaluation and to store the resulting impression. In addition, split must exist in the environment.
|
217
|
-
|
218
|
-
- `attributes`: must be of type `Hash`.
|
219
|
-
|
220
|
-
#### get_treatments (split_client)
|
221
|
-
|
222
|
-
- `key`, `matching_key`, `bucketing_key`: same rules as those for `get_treatment` apply.
|
223
|
-
|
224
|
-
- `split_names`: must be an non-empty Array. Split names will be filtered removing those not matching the corresponding rules for `split_name` in `get_treatment`. In addition, duplicates will be removed.
|
225
|
-
|
226
|
-
#### track (split_client)
|
227
|
-
|
228
|
-
- `key`: must be a non-empty `String` or a `Symbol`, shorter than 250 characters. If a non-NaN `Numeric` value is used, it'll be converted to its `String` representation.
|
229
|
-
|
230
|
-
- `traffic_type_name`: must be a non-empty `String` or a `Symbol`. If `traffic_type_name` contains uppercase letters, it will be lowercased.
|
231
|
-
|
232
|
-
- `event_type`: must be a non-empty `String` or `Symbol` that conforms with the regular expression `^[a-zA-Z0-9][-_.:a-zA-Z0-9]{0,79}$` (i.e. event name must be alphanumeric, cannot be more than 80 characters long, and can only include a dash, underscore, period, or colon as separators of alphanumeric characters).
|
233
|
-
|
234
|
-
- `value`: must be either a non-NaN `Numeric` value, or nil.
|
235
|
-
|
236
|
-
#### split (split_manager)
|
237
|
-
|
238
|
-
- `split_name`: must be a non-empty `String` or a `Symbol`. In addition, split must exist in the environment.
|
239
|
-
|
240
|
-
#### Configuration Parameters
|
241
|
-
|
242
|
-
- `api_key`: must be a non-empty `String` or a `Symbol` of type `sdk` (`browser` type API keys will break this rule).
|
243
|
-
|
244
|
-
#### Client Destroyed Rules
|
245
|
-
Calls to the SDK methods are still possible after `destroy` is called. All will log an error message stating _client has been destroyed_.
|
246
|
-
|
247
|
-
- `get_treatment` will return `control` for all calls (`get_treatments`, will return an Array of `control` values, correspondingly).
|
248
|
-
|
249
|
-
- Calls to `track` will return `false`.
|
250
|
-
|
251
|
-
- All calls to `split_manager` methods will return an empty Array, except `split`, which will return `nil`.
|
252
|
-
|
253
|
-
|
254
|
-
## Advanced Configuration
|
255
|
-
|
256
|
-
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.:
|
257
|
-
|
258
|
-
```ruby
|
259
|
-
options = {
|
260
|
-
impressions_refresh_rate: 10,
|
261
|
-
debug_enabled: true,
|
262
|
-
transport_debug_enabled: false
|
263
|
-
}
|
264
|
-
|
265
|
-
factory = SplitIoClient::SplitFactoryBuilder.build('your_api_key'], options)
|
266
|
-
```
|
267
|
-
|
268
|
-
The following values can be customized:
|
269
|
-
|
270
|
-
**base_uri** : URI for the api endpoints.
|
271
|
-
|
272
|
-
*default value* = `https://sdk.split.io/api/`
|
273
|
-
|
274
|
-
**connection_timeout** : Http client connection timeout (in seconds).
|
275
|
-
|
276
|
-
*default value* = `5`
|
277
|
-
|
278
|
-
**read_timeout** : Http socket read timeout (in seconds).
|
279
|
-
|
280
|
-
*default value* = `5`
|
281
|
-
|
282
|
-
**features_refresh_rate** : The SDK polls Split servers for changes to feature Splits every X seconds, where X is this property's value.
|
283
|
-
|
284
|
-
*default value* = `5`
|
285
|
-
|
286
|
-
**segments_refresh_rate** : The SDK polls Split servers for changes to segments every X seconds, where X is this property's value.
|
287
|
-
|
288
|
-
*default value* = `60`
|
289
|
-
|
290
|
-
**metrics_refresh_rate** : The SDK sends and flushes diagnostic metrics to Split servers every X seconds where X is this property's value.
|
291
|
-
|
292
|
-
*default value* = `60`
|
293
|
-
|
294
|
-
**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).
|
295
|
-
|
296
|
-
*default value* = `60`
|
297
|
-
|
298
|
-
**impressions_queue_size** : The size of the impressions queue in case of `cache_adapter == :memory`. When the queue is full, existing impressions will be dropped.
|
299
|
-
|
300
|
-
*default value* = 5000
|
301
|
-
|
302
|
-
**impressions_bulk_size** : Maximum number of impressions to be sent to Split servers on each post.
|
303
|
-
|
304
|
-
*default value* = defaults to `impressions_queue_size`
|
305
|
-
|
306
|
-
**events_queue_size** : The size of the events queue in case of `cache_adapter == :memory`. When the queue is full, existing events will be dropped.
|
307
|
-
|
308
|
-
*default value* = 500
|
309
|
-
|
310
|
-
**debug_enabled** : Enables extra logging (verbose mode).
|
311
|
-
|
312
|
-
*default value* = `false`
|
313
|
-
|
314
|
-
**transport_debug_enabled** : Super verbose mode that prints network payloads among others.
|
315
|
-
|
316
|
-
*default value* = `false`
|
317
|
-
|
318
|
-
**logger** : Default logger for messages and errors.
|
319
|
-
|
320
|
-
*default value* = `Logger.new($stdout)`
|
321
|
-
|
322
|
-
**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._
|
323
|
-
|
324
|
-
*default value* = (no impression listener)
|
325
|
-
|
326
|
-
**labels_enabled** : Allows preventing labels from being sent to the Split servers, as they may contain sensitive information.
|
327
|
-
|
328
|
-
*default value* = `true`
|
329
|
-
|
330
|
-
**mode** : See [SDK Modes](#sdk-modes).
|
331
|
-
|
332
|
-
*default value* = `:standalone`
|
333
|
-
|
334
|
-
**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`.
|
335
|
-
|
336
|
-
_To use Redis, include `redis-rb` in your app's Gemfile._
|
337
|
-
|
338
|
-
*default value* = `:memory`
|
339
|
-
|
340
|
-
**redis_namespace** : Prefix to add to elements in Redis cache when having to share redis with other applications.
|
341
|
-
|
342
|
-
*default value* = `SPLITIO`
|
343
|
-
|
344
|
-
**language** : SDK language (used in the Redis namespace for metrics and impressions, also included in requests' headers).
|
345
|
-
|
346
|
-
*default value* = `'ruby'`
|
347
|
-
|
348
|
-
**version** : SDK version (used in the Redis namespace for metrics and impressions, also included in requests' headers).
|
349
|
-
|
350
|
-
*default value* = (current version of the SDK)
|
351
|
-
|
352
|
-
**machine_ip** : SDK machine ip (used in the Redis namespace for metrics and impressions, also included in requests' headers).
|
353
|
-
|
354
|
-
*default value* = (your current host's ip)
|
355
|
-
|
356
|
-
**machine_name** : SDK machine name (used in the Redis namespace for metrics and impressions, also included in requests' headers).
|
357
|
-
|
358
|
-
*default value* = (your current hostname)
|
359
|
-
|
360
|
-
**cache_ttl** : Time to live in seconds for the memory cache values when using Redis.
|
361
|
-
|
362
|
-
*default value* = `5`
|
363
|
-
|
364
|
-
**max_cache_size** : Maximum number of items held in the memory cache values when using Redis. When cache is full an LRU strategy for pruning shall be used.
|
365
|
-
|
366
|
-
*default value* = `500`
|
367
|
-
|
368
|
-
**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.
|
369
|
-
|
370
|
-
*default value* = `'redis://127.0.0.1:6379/0'`
|
371
|
-
|
372
|
-
_You can also use [Redis Sentinel](https://redis.io/topics/sentinel) by providing an array of sentinels in the Redis configuration:_
|
373
|
-
|
374
|
-
```ruby
|
375
|
-
SENTINELS = [{host: '127.0.0.1', port: 26380},
|
376
|
-
{host: '127.0.0.1', port: 26381}]
|
377
|
-
|
378
|
-
options = {
|
379
|
-
# Other options here
|
380
|
-
redis_url: { url: 'redis://mymaster', sentinels: SENTINELS, role: :master }
|
381
|
-
}
|
382
|
-
```
|
383
|
-
### Sample Configuration Using Redis
|
384
|
-
---
|
385
|
-
|
386
|
-
```ruby
|
387
|
-
options = {
|
388
|
-
# other options
|
389
|
-
cache_adapter: :redis,
|
390
|
-
mode: :consumer,
|
391
|
-
redis_url: 'redis://127.0.0.1:6379/0'
|
392
|
-
}
|
393
|
-
|
394
|
-
split_client = SplitIoClient::SplitFactoryBuilder.build('YOUR_API_KEY', options).client
|
395
|
-
```
|
396
|
-
|
397
|
-
### Logging
|
398
|
-
---
|
399
|
-
|
400
|
-
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:
|
401
|
-
|
402
|
-
```ruby
|
403
|
-
logger: Logger.new('logfile.log'), # Logger class instance.
|
404
|
-
debug_enabled: true, # Verbose logging.
|
405
|
-
transport_debug_enabled: true # Super verbose logging, including http request data.
|
406
|
-
```
|
407
|
-
|
408
|
-
_Refer to [Advanced Configuration](#advanced-configuration) for more information._
|
409
|
-
|
410
|
-
#### Impression Listener
|
411
|
-
|
412
|
-
The SDK provides an optional featured called Impression Listener, that captures every single impression in your app.
|
413
|
-
|
414
|
-
To set up an Impression Listener, define a class that implements a `log` instance method, which must receive the `impression` argument. e.g.:
|
415
|
-
|
416
|
-
```ruby
|
417
|
-
class MyImpressionListener
|
418
|
-
def log(impression)
|
419
|
-
Logger.new($stdout).info(impression)
|
420
|
-
end
|
421
|
-
end
|
422
|
-
```
|
423
|
-
|
424
|
-
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:
|
425
|
-
|
426
|
-
```ruby
|
427
|
-
{
|
428
|
-
# other options
|
429
|
-
impression_listener: MyImpressionListener.new # remember to initialize your class here
|
430
|
-
}
|
431
|
-
```
|
432
|
-
|
433
|
-
### SDK Modes
|
434
|
-
---
|
435
|
-
|
436
|
-
The SDK is capable of running in two different modes to fit in different infrastructure configurations:
|
437
|
-
|
438
|
-
- `:standalone` - (default) : The SDK will retrieve information (e.g. split definitions) periodically from the Split servers, and store it in the memory cache. 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. _This mode is only available when using the `memory` cache adapter._
|
439
|
-
- `: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. _This mode is only available when using the `redis` cache adapter. In addition, note that `block_until_ready` has no effect in this mode_
|
440
|
-
|
441
|
-
_You can choose between these 2 modes setting the `mode` option in the config. An invalid combination of `cache_adaper` and `mode` will result in an Invalid Mode exception being raised._
|
442
|
-
|
443
|
-
## SDK Server Compatibility
|
444
|
-
|
445
|
-
The Split Ruby SDK has been tested as a standalone app as well as using the following web servers:
|
446
|
-
- Thin
|
447
|
-
- Puma
|
448
|
-
- Passenger
|
449
|
-
- Unicorn
|
450
|
-
|
451
|
-
For other setups, please reach out to [support@split.io](mailto:support@split.io).
|
452
|
-
|
453
|
-
### Server Compatibility Notes
|
454
|
-
---
|
455
|
-
|
456
|
-
#### Unicorn and Puma in cluster mode (only for "memory mode")
|
457
|
-
|
458
|
-
During the start of your application, the SDK spawns multiple threads. Each thread has an infinite loop inside,
|
459
|
-
which is used to fetch splits/segments or send impressions/metrics to the Split service continuously.
|
460
|
-
When using Unicorn or Puma in cluster mode (i.e. with `workers` > 0) the application
|
461
|
-
server will spawn multiple child processes, but they won't recreate the threads that existed in the parent process.
|
462
|
-
So, if your application is running in Unicorn or Puma in cluster mode you need to make two small extra steps.
|
463
|
-
|
464
|
-
For both servers you will need to have the following line in your `config/initializers/splitclient.rb`:
|
465
|
-
|
466
|
-
```ruby
|
467
|
-
Rails.configuration.split_factory = factory
|
468
|
-
```
|
469
|
-
|
470
|
-
#### Unicorn
|
471
|
-
|
472
|
-
If you’re using Unicorn you’ll need to include these lines in your Unicorn config (likely `config/unicorn.rb`):
|
473
|
-
|
474
|
-
```ruby
|
475
|
-
before_fork do |server, worker|
|
476
|
-
# keep your existing before_fork code if any
|
477
|
-
Rails.configuration.split_factory.stop!
|
478
|
-
end
|
479
|
-
|
480
|
-
after_fork do |server, worker|
|
481
|
-
# keep your existing after_fork code if any
|
482
|
-
Rails.configuration.split_factory.resume!
|
483
|
-
end
|
484
|
-
```
|
485
|
-
|
486
|
-
#### Puma
|
487
|
-
|
488
|
-
If using Puma in cluster mode, add these lines to your Puma config (likely `config/puma.rb`):
|
489
|
-
|
490
|
-
```ruby
|
491
|
-
before_fork do
|
492
|
-
# keep your existing before_fork code if any
|
493
|
-
Rails.configuration.split_factory.stop!
|
494
|
-
end
|
495
|
-
|
496
|
-
on_worker_boot do
|
497
|
-
# keep your existing on_worker_boot code if any
|
498
|
-
Rails.configuration.split_factory.resume!
|
499
|
-
end
|
500
|
-
```
|
501
|
-
|
502
|
-
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.
|
503
|
-
|
504
|
-
## Proxy Support
|
505
|
-
|
506
|
-
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:
|
507
|
-
|
508
|
-
```
|
509
|
-
http_proxy=http://username:password@hostname:port
|
510
|
-
```
|
511
|
-
|
512
|
-
## Development Notes
|
513
|
-
|
514
|
-
Check out the repository and run `bin/setup` to install dependencies. You can also run `bin/console` to get an interactive prompt.
|
515
|
-
|
516
|
-
To install this gem onto your local machine, run `bundle exec rake install`.
|
517
|
-
|
518
|
-
### Tests & Coverage
|
519
|
-
---
|
520
|
-
|
521
|
-
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.
|
522
|
-
|
523
|
-
To run all the specs in the `spec` folder, use the provided rake task (_make sure Redis is running in localhost_):
|
524
|
-
|
525
|
-
```bash
|
526
|
-
bundle exec rspec
|
527
|
-
```
|
528
|
-
|
529
|
-
`Simplecov` is used for coverage reporting. Upon executing the rake task it will store the reports in the `/coverage` folder.
|
530
|
-
|
531
|
-
### Benchmarks
|
532
|
-
---
|
533
|
-
|
534
|
-
To benchmark the hashing algorithms (MurmurHash) run:
|
535
|
-
|
536
|
-
```bash
|
537
|
-
bundle exec rake benchmark_hashing_algorithm
|
538
|
-
```
|
539
|
-
|
540
|
-
### Contribute
|
541
|
-
---
|
542
|
-
|
543
|
-
Bug reports and pull requests are welcome on GitHub at https://github.com/splitio/ruby-client.
|
544
|
-
|
545
|
-
### Release
|
546
|
-
---
|
547
|
-
|
548
|
-
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`.
|
549
|
-
**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.
|
550
|
-
|
551
|
-
To build a new version of the gem after making the changes specified above, run:
|
552
|
-
|
553
|
-
```bash
|
554
|
-
gem build splitclient-rb.gemspec
|
555
|
-
```
|
556
|
-
|
557
|
-
That will generate a `splitclient-rb-x.x.x.gem` file, with the corresponding version information on it.
|
558
|
-
To release the new version of the gem at [rubygems.org](rubygems.org) run the following command:
|
559
|
-
|
560
|
-
```bash
|
561
|
-
gem push splitclient-rb-x.x.x.gem
|
562
|
-
```
|
563
|
-
|
564
|
-
_A valid rubygems username and password is required._
|
565
|
-
|
566
|
-
Once released, `splitclient-rb-x.x.x` version will be available for use in any ruby application.
|
567
|
-
|
568
|
-
To get a specific gem version in a Rails application that uses Bundler, add this line to your gemfile:
|
569
|
-
|
570
|
-
```ruby
|
571
|
-
gem 'splitclient-rb', '~> x.x.x'
|
572
|
-
```
|
573
|
-
|
574
|
-
## License
|
575
|
-
|
576
|
-
The gem is available as open source under the terms of the [Apache License](http://www.apache.org/licenses/).
|