splitclient-rb 5.0.3 → 5.1.0.pre.rc1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +15 -0
- data/Detailed-README.md +246 -313
- data/Gemfile +2 -0
- data/Rakefile +6 -2
- data/exe/splitio +20 -20
- data/ext/murmurhash/extconf.rb +3 -1
- data/lib/splitclient-rb/engine/api/client.rb +1 -2
- data/lib/splitclient-rb/engine/api/segments.rb +33 -27
- data/lib/splitclient-rb/engine/api/splits.rb +22 -17
- data/lib/splitclient-rb/split_config.rb +1 -1
- data/lib/splitclient-rb/split_logger.rb +29 -0
- data/lib/splitclient-rb/version.rb +1 -1
- data/lib/splitclient-rb.rb +1 -0
- data/splitclient-rb.gemspec +38 -34
- data/tasks/benchmark_get_treatment.rake +31 -17
- data/tasks/irb.rake +5 -3
- data/tasks/rspec.rake +3 -1
- metadata +69 -25
data/Gemfile
CHANGED
data/Rakefile
CHANGED
@@ -1,11 +1,15 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'bundler/gem_tasks'
|
2
4
|
require 'rspec/core/rake_task'
|
5
|
+
require 'rubocop/rake_task'
|
3
6
|
|
4
7
|
Dir['tasks/**/*.rake'].each { |rake| load rake }
|
5
8
|
|
6
9
|
RSpec::Core::RakeTask.new(:spec)
|
10
|
+
RuboCop::RakeTask.new(:rubocop)
|
7
11
|
|
8
|
-
task :
|
12
|
+
task spec: :compile
|
9
13
|
case RUBY_PLATFORM
|
10
14
|
when 'java'
|
11
15
|
require 'rake/javaextensiontask'
|
@@ -21,4 +25,4 @@ else
|
|
21
25
|
end
|
22
26
|
end
|
23
27
|
|
24
|
-
task :
|
28
|
+
task default: %i[spec rubocop]
|
data/exe/splitio
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
2
3
|
|
3
|
-
lib = File.expand_path('
|
4
|
+
lib = File.expand_path('../lib', __dir__)
|
4
5
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
5
6
|
|
6
7
|
require 'optparse'
|
@@ -12,65 +13,65 @@ require_relative '../lib/splitclient-rb'
|
|
12
13
|
config_path = ''
|
13
14
|
options = {}
|
14
15
|
opt_parser = OptionParser.new do |opts|
|
15
|
-
opts.banner =
|
16
|
+
opts.banner = 'Usage: splitio [options]'
|
16
17
|
|
17
|
-
opts.on(
|
18
|
+
opts.on('-cPATH', '--config=PATH', 'Set the path to splitio.yml config file') do |c|
|
18
19
|
config_path = c
|
19
20
|
end
|
20
21
|
|
21
|
-
opts.on(
|
22
|
+
opts.on('--base-uri=BASE_URI', 'Set the base uri for Split SDK') do |c|
|
22
23
|
options[:base_uri] = c
|
23
24
|
end
|
24
25
|
|
25
|
-
opts.on(
|
26
|
+
opts.on('--events-uri=EVENTS_URI', 'Set the events uri for Split SDK') do |c|
|
26
27
|
options[:events_uri] = c
|
27
28
|
end
|
28
29
|
|
29
|
-
opts.on(
|
30
|
+
opts.on('--api-key=API_KEY', 'Set the API Key for Split SDK') do |c|
|
30
31
|
options[:api_key] = c
|
31
32
|
end
|
32
33
|
|
33
|
-
opts.on(
|
34
|
+
opts.on('--read-timeout=READ_TIMEOUT', 'Read timeout in seconds') do |c|
|
34
35
|
options[:read_timeout] = c
|
35
36
|
end
|
36
37
|
|
37
|
-
opts.on(
|
38
|
+
opts.on('--connection-timeout=CONNECTION_TIMEOUT', 'Connection timeout in seconds') do |c|
|
38
39
|
options[:connection_timeout] = c
|
39
40
|
end
|
40
41
|
|
41
|
-
opts.on(
|
42
|
+
opts.on('--features-refresh-rate=FEATURES_REFRESH_RATE', 'Features refresh rate in seconds') do |c|
|
42
43
|
options[:features_refresh_rate] = c
|
43
44
|
end
|
44
45
|
|
45
|
-
opts.on(
|
46
|
+
opts.on('--segments-refresh-rate=SEGMENTS_REFRESH_RATE', 'Segments refresh rate in seconds') do |c|
|
46
47
|
options[:segments_refresh_rate] = c
|
47
48
|
end
|
48
49
|
|
49
|
-
opts.on(
|
50
|
+
opts.on('--metrics-refresh-rate=METRICS_REFRESH_RATE', 'Metrics refresh rate in seconds') do |c|
|
50
51
|
options[:metrics_refresh_rate] = c
|
51
52
|
end
|
52
53
|
|
53
|
-
opts.on(
|
54
|
+
opts.on('--impressions-refresh-rate=IMPRESSIONS_REFRESH_RATE', 'Impressions refresh rate in seconds') do |c|
|
54
55
|
options[:impressions_refresh_rate] = c
|
55
56
|
end
|
56
57
|
|
57
|
-
opts.on(
|
58
|
+
opts.on('--ready=SECONDS', 'Seconds to block the app until SDK is ready or false to run in non-blocking mode') do |c|
|
58
59
|
options[:ready] = c
|
59
60
|
end
|
60
61
|
|
61
|
-
opts.on(
|
62
|
+
opts.on('--redis-url=REDIS_URL', 'Set base uri for Split SDK') do |c|
|
62
63
|
options[:redis_url] = c
|
63
64
|
end
|
64
65
|
|
65
|
-
opts.on(
|
66
|
+
opts.on('--transport-debug', 'Enable transport debug') do
|
66
67
|
options[:transport_debug_enabled] = true
|
67
68
|
end
|
68
69
|
|
69
|
-
opts.on(
|
70
|
+
opts.on('-d', '--debug', 'Enable debug mode') do
|
70
71
|
options[:debug_enabled] = true
|
71
72
|
end
|
72
73
|
|
73
|
-
opts.on_tail(
|
74
|
+
opts.on_tail('-h', '--help', 'Prints this help') do
|
74
75
|
puts opts
|
75
76
|
exit
|
76
77
|
end
|
@@ -89,8 +90,7 @@ config
|
|
89
90
|
.merge!(mode: :producer, cache_adapter: :redis)
|
90
91
|
.merge!(options)
|
91
92
|
.merge!(api_key: ENV['API_KEY'] || config[:api_key])
|
92
|
-
.merge!(base_uri: ENV['SDK_URI'] || config[:base_uri])
|
93
|
-
|
94
|
-
# IDENTIFY_BASE_URI
|
93
|
+
.merge!(base_uri: ENV['SDK_URI'] || config[:base_uri])[:events_uri] = ENV['EVENTS_URI'] || config[:events_uri]
|
94
|
+
# IDENTIFY_BASE_URI
|
95
95
|
|
96
96
|
SplitIoClient::SplitFactory.new(config[:api_key], config)
|
data/ext/murmurhash/extconf.rb
CHANGED
@@ -16,8 +16,7 @@ module SplitIoClient
|
|
16
16
|
end
|
17
17
|
rescue StandardError => e
|
18
18
|
config.logger.warn("#{e}\nURL:#{url}\nparams:#{params}")
|
19
|
-
|
20
|
-
false
|
19
|
+
raise 'Split SDK failed to connect to backend to retrieve information'
|
21
20
|
end
|
22
21
|
|
23
22
|
def post_api(url, config, api_key, data, headers = {}, params = {})
|
@@ -1,6 +1,11 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module SplitIoClient
|
2
4
|
module Api
|
5
|
+
# Retrieves segment changes from the Split Backend
|
3
6
|
class Segments < Client
|
7
|
+
METRICS_PREFIX = 'segmentChangeFetcher'
|
8
|
+
|
4
9
|
def initialize(api_key, config, metrics, segments_repository)
|
5
10
|
@config = config
|
6
11
|
@metrics = metrics
|
@@ -10,52 +15,53 @@ module SplitIoClient
|
|
10
15
|
|
11
16
|
def store_segments_by_names(names)
|
12
17
|
start = Time.now
|
13
|
-
prefix = 'segmentChangeFetcher'
|
14
18
|
|
15
19
|
return if names.nil? || names.empty?
|
16
20
|
|
17
21
|
names.each do |name|
|
18
22
|
since = @segments_repository.get_change_number(name)
|
19
|
-
|
20
|
-
|
21
|
-
@
|
23
|
+
loop do
|
24
|
+
segment = fetch_segment_changes(name, since)
|
25
|
+
@segments_repository.add_to_segment(segment)
|
22
26
|
|
23
|
-
|
27
|
+
SplitLogger.log_if_debug("Segment #{name} fetched before: #{since}, \
|
28
|
+
till: #{@segments_repository.get_change_number(name)}")
|
29
|
+
|
30
|
+
break if since.to_i >= @segments_repository.get_change_number(name).to_i
|
24
31
|
since = @segments_repository.get_change_number(name)
|
25
32
|
end
|
26
33
|
end
|
27
34
|
|
28
35
|
latency = (Time.now - start) * 1000.0
|
29
|
-
@metrics.time(
|
36
|
+
@metrics.time(METRICS_PREFIX + '.time', latency)
|
30
37
|
end
|
31
38
|
|
32
39
|
private
|
33
40
|
|
34
|
-
def
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
@
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
@config.logger.debug("\'#{segment_content[:name]}\' #{segment_content[:removed].size} removed keys") if segment_content[:removed].size > 0
|
41
|
+
def fetch_segment_changes(name, since)
|
42
|
+
response = get_api("#{@config.base_uri}/segmentChanges/#{name}", @config, @api_key, since: since)
|
43
|
+
|
44
|
+
if response.success?
|
45
|
+
segment = JSON.parse(response.body, symbolize_names: true)
|
46
|
+
@segments_repository.set_change_number(name, segment[:till])
|
47
|
+
@metrics.count(METRICS_PREFIX + '.status.' + response.status.to_s, 1)
|
48
|
+
|
49
|
+
SplitLogger.log_if_debug("\'#{segment[:name]}\' segment retrieved.")
|
50
|
+
unless segment[:added].empty?
|
51
|
+
SplitLogger.log_if_debug("\'#{segment[:name]}\' #{segment[:added].size} added keys")
|
52
|
+
end
|
53
|
+
unless segment[:removed].empty?
|
54
|
+
SplitLogger.log_if_debug("\'#{segment[:name]}\' #{segment[:removed].size} removed keys")
|
49
55
|
end
|
50
|
-
|
56
|
+
SplitLogger.log_if_transport(segment.to_s)
|
51
57
|
|
52
|
-
|
58
|
+
segment
|
53
59
|
else
|
54
|
-
|
55
|
-
|
60
|
+
SplitLogger.log_error("Unexpected status code while fetching segments: #{response.status}." \
|
61
|
+
"Since #{since} - Check your API key and base URI")
|
62
|
+
@metrics.count(METRICS_PREFIX + '.status.' + response.status.to_s, 1)
|
63
|
+
raise 'Split SDK failed to connect to backend to fetch segments'
|
56
64
|
end
|
57
|
-
|
58
|
-
segments
|
59
65
|
end
|
60
66
|
end
|
61
67
|
end
|
@@ -1,6 +1,11 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module SplitIoClient
|
2
4
|
module Api
|
5
|
+
# Retrieves split definitions from the Split Backend
|
3
6
|
class Splits < Client
|
7
|
+
METRICS_PREFIX = 'splitChangeFetcher'
|
8
|
+
|
4
9
|
def initialize(api_key, config, metrics)
|
5
10
|
@api_key = api_key
|
6
11
|
@config = config
|
@@ -9,28 +14,28 @@ module SplitIoClient
|
|
9
14
|
|
10
15
|
def since(since)
|
11
16
|
start = Time.now
|
12
|
-
prefix = 'splitChangeFetcher'
|
13
|
-
splits = get_api("#{@config.base_uri}/splitChanges", @config, @api_key, since: since)
|
14
17
|
|
15
|
-
|
16
|
-
@config.logger.error("Failed to make a http request")
|
17
|
-
elsif splits.status / 100 == 2
|
18
|
-
result = splits_with_segment_names(splits.body)
|
18
|
+
response = get_api("#{@config.base_uri}/splitChanges", @config, @api_key, since: since)
|
19
19
|
|
20
|
-
|
21
|
-
|
22
|
-
@config.logger.debug("#{result[:splits].length} splits retrieved. since=#{since}") if @config.debug_enabled and result[:splits].length > 0
|
23
|
-
@config.logger.debug("#{result}") if @config.transport_debug_enabled
|
24
|
-
else
|
25
|
-
@metrics.count(prefix + '.status.' + splits.status.to_s, 1)
|
20
|
+
if response.success?
|
21
|
+
result = splits_with_segment_names(response.body)
|
26
22
|
|
27
|
-
@
|
28
|
-
|
23
|
+
@metrics.count(METRICS_PREFIX + '.status.' + response.status.to_s, 1)
|
24
|
+
unless result[:splits].empty?
|
25
|
+
SplitLogger.log_if_debug("#{result[:splits].length} splits retrieved. since=#{since}")
|
26
|
+
end
|
27
|
+
SplitLogger.log_if_transport(result.to_s)
|
29
28
|
|
30
|
-
|
31
|
-
|
29
|
+
latency = (Time.now - start) * 1000.0
|
30
|
+
@metrics.time(METRICS_PREFIX + '.time', latency)
|
32
31
|
|
33
|
-
|
32
|
+
result
|
33
|
+
else
|
34
|
+
@metrics.count(METRICS_PREFIX + '.status.' + response.status.to_s, 1)
|
35
|
+
SplitLogger.log_error("Unexpected status code while fetching splits: #{response.status}. " \
|
36
|
+
'Check your API key and base URI')
|
37
|
+
raise 'Split SDK failed to connect to backend to fetch split definitions'
|
38
|
+
end
|
34
39
|
end
|
35
40
|
|
36
41
|
private
|
@@ -76,7 +76,7 @@ module SplitIoClient
|
|
76
76
|
@events_adapter = SplitConfig.init_cache_adapter(
|
77
77
|
opts[:cache_adapter] || SplitConfig.default_cache_adapter, :queue_adapter, @redis_url, @events_queue_size
|
78
78
|
)
|
79
|
-
|
79
|
+
SplitIoClient::SplitLogger.split_config(self)
|
80
80
|
startup_log
|
81
81
|
end
|
82
82
|
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require 'singleton'
|
2
|
+
|
3
|
+
module SplitIoClient
|
4
|
+
class SplitLogger
|
5
|
+
attr_accessor :config
|
6
|
+
include Singleton
|
7
|
+
|
8
|
+
def self.split_config(config)
|
9
|
+
instance.config = config
|
10
|
+
end
|
11
|
+
|
12
|
+
def log_if_debug(message)
|
13
|
+
config.logger.debug(message) if config.debug_enabled
|
14
|
+
end
|
15
|
+
|
16
|
+
def log_if_transport(message)
|
17
|
+
config.logger.debug(message) if config.transport_debug_enabled
|
18
|
+
end
|
19
|
+
|
20
|
+
def log_error(message)
|
21
|
+
config.logger.error(message)
|
22
|
+
end
|
23
|
+
|
24
|
+
class << self
|
25
|
+
extend Forwardable
|
26
|
+
def_delegators :instance, *SplitLogger.instance_methods(false)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
data/lib/splitclient-rb.rb
CHANGED
@@ -38,6 +38,7 @@ require 'splitclient-rb/split_factory'
|
|
38
38
|
require 'splitclient-rb/split_factory_builder'
|
39
39
|
require 'splitclient-rb/localhost_split_factory'
|
40
40
|
require 'splitclient-rb/split_config'
|
41
|
+
require 'splitclient-rb/split_logger'
|
41
42
|
|
42
43
|
require 'splitclient-rb/engine/api/faraday_middleware/gzip'
|
43
44
|
require 'splitclient-rb/engine/api/client'
|
data/splitclient-rb.gemspec
CHANGED
@@ -1,53 +1,57 @@
|
|
1
|
-
#
|
2
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
lib = File.expand_path('lib', __dir__)
|
3
4
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
5
|
require 'splitclient-rb/version'
|
5
6
|
|
6
7
|
Gem::Specification.new do |spec|
|
7
|
-
spec.name =
|
8
|
+
spec.name = 'splitclient-rb'
|
8
9
|
spec.version = SplitIoClient::VERSION
|
9
|
-
spec.authors = [
|
10
|
-
spec.email = [
|
10
|
+
spec.authors = ['Split Software']
|
11
|
+
spec.email = ['pato@split.io']
|
11
12
|
|
12
|
-
spec.summary =
|
13
|
-
spec.description =
|
14
|
-
spec.homepage =
|
15
|
-
spec.license =
|
13
|
+
spec.summary = 'Ruby client for split SDK.'
|
14
|
+
spec.description = 'Ruby client for using split SDK.'
|
15
|
+
spec.homepage = 'https://github.com/splitio/ruby-client'
|
16
|
+
spec.license = 'Apache 2.0'
|
16
17
|
|
17
18
|
spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(spec|features|ext)/}) }
|
18
19
|
|
19
|
-
spec.bindir =
|
20
|
+
spec.bindir = 'exe'
|
20
21
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
21
|
-
spec.require_paths = [
|
22
|
+
spec.require_paths = ['lib']
|
22
23
|
|
23
24
|
if defined?(JRUBY_VERSION)
|
24
25
|
spec.platform = 'java'
|
25
|
-
spec.files.concat(
|
26
|
-
ext/murmurhash/MurmurHash3.java
|
27
|
-
|
26
|
+
spec.files.concat(
|
27
|
+
%w[ext/murmurhash/MurmurHash3.java
|
28
|
+
lib/murmurhash/murmurhash.jar]
|
28
29
|
)
|
29
30
|
else
|
30
|
-
spec.files.concat(
|
31
|
-
ext/murmurhash/3_x86_32.c
|
32
|
-
|
33
|
-
|
34
|
-
|
31
|
+
spec.files.concat(
|
32
|
+
%w[ext/murmurhash/3_x86_32.c
|
33
|
+
ext/murmurhash/extconf.rb
|
34
|
+
ext/murmurhash/murmurhash.c
|
35
|
+
ext/murmurhash/murmurhash.h]
|
35
36
|
)
|
36
|
-
spec.extensions = [
|
37
|
+
spec.extensions = ['ext/murmurhash/extconf.rb']
|
37
38
|
end
|
38
39
|
|
39
|
-
spec.add_development_dependency
|
40
|
-
spec.add_development_dependency
|
41
|
-
spec.add_development_dependency
|
42
|
-
spec.add_development_dependency
|
43
|
-
spec.add_development_dependency
|
44
|
-
spec.add_development_dependency
|
45
|
-
spec.add_development_dependency
|
46
|
-
|
47
|
-
spec.
|
48
|
-
spec.
|
49
|
-
|
50
|
-
spec.add_runtime_dependency
|
51
|
-
spec.add_runtime_dependency
|
52
|
-
spec.add_runtime_dependency
|
40
|
+
spec.add_development_dependency 'allocation_stats'
|
41
|
+
spec.add_development_dependency 'bundler', '~> 1.11'
|
42
|
+
spec.add_development_dependency 'pry'
|
43
|
+
spec.add_development_dependency 'pry-nav'
|
44
|
+
spec.add_development_dependency 'rake', '~> 10.0'
|
45
|
+
spec.add_development_dependency 'rake-compiler'
|
46
|
+
spec.add_development_dependency 'rspec'
|
47
|
+
spec.add_development_dependency 'rubocop'
|
48
|
+
spec.add_development_dependency 'simplecov'
|
49
|
+
spec.add_development_dependency 'webmock'
|
50
|
+
|
51
|
+
spec.add_runtime_dependency 'concurrent-ruby', '~> 1.0'
|
52
|
+
spec.add_runtime_dependency 'faraday', '>= 0.8'
|
53
|
+
spec.add_runtime_dependency 'json', '>= 1.8'
|
54
|
+
spec.add_runtime_dependency 'net-http-persistent', '~> 2.9'
|
55
|
+
spec.add_runtime_dependency 'redis', '>= 3.2'
|
56
|
+
spec.add_runtime_dependency 'thread_safe', '>= 0.3'
|
53
57
|
end
|
@@ -1,13 +1,17 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
desc 'Benchmark the get_treatment method call in 4 threads'
|
2
4
|
|
3
5
|
# Usage:
|
4
|
-
# rake concurrent_benchmark api_key=YOUR_API_KEY base_uri=YOUR_API_BASE_URI
|
6
|
+
# rake concurrent_benchmark api_key=YOUR_API_KEY base_uri=YOUR_API_BASE_URI
|
7
|
+
# [iterations=NUMBER_OF_ITERATIONS] [user_id=A_USER_ID] [feature_id=A_FEATURE_ID]
|
5
8
|
task :concurrent_benchmark do
|
6
9
|
require 'benchmark'
|
7
10
|
require 'splitclient-rb'
|
8
11
|
|
9
|
-
usage_message =
|
10
|
-
|
12
|
+
usage_message = 'Usage: rake concurrent_benchmark api_key=YOUR_API_KEY base_uri=YOUR_API_BASE_URI \
|
13
|
+
[iterations=NUMBER_OF_ITERATIONS] [user_id=A_USER_ID] [feature_id=A_FEATURE_ID]'
|
14
|
+
|
11
15
|
if validate_params
|
12
16
|
execute
|
13
17
|
else
|
@@ -19,25 +23,35 @@ def validate_params
|
|
19
23
|
!ENV['api_key'].nil? && !ENV['base_uri'].nil?
|
20
24
|
end
|
21
25
|
|
22
|
-
def
|
23
|
-
api_key = ENV['api_key'].nil? ?
|
24
|
-
base_uri = ENV['base_uri'].nil? ?
|
25
|
-
|
26
|
-
|
27
|
-
feature_id = ENV['feature_id'].nil? ? "sample_feature" : ENV['feature_id']
|
26
|
+
def split_client
|
27
|
+
api_key = ENV['api_key'].nil? ? 'fake_api_key' : ENV['api_key']
|
28
|
+
base_uri = ENV['base_uri'].nil? ? 'fake/api/' : ENV['base_uri']
|
29
|
+
SplitIoClient::SplitFactory.new(api_key, base_uri: base_uri, logger: Logger.new('/dev/null').client)
|
30
|
+
end
|
28
31
|
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
+
def times_per_thread
|
33
|
+
iterations = ENV['iterations'].nil? ? 1_000_000 : ENV['iterations'].to_i
|
34
|
+
iterations / 4
|
35
|
+
end
|
32
36
|
|
33
|
-
|
34
|
-
|
37
|
+
def feature_id
|
38
|
+
ENV['feature_id'].nil? ? 'sample_feature' : ENV['feature_id']
|
39
|
+
end
|
40
|
+
|
41
|
+
def user_id
|
42
|
+
ENV['user_id'].nil? ? 'fake_id_1' : ENV['user_id']
|
43
|
+
end
|
44
|
+
|
45
|
+
def execute
|
46
|
+
threads = []
|
47
|
+
puts Benchmark.measure do
|
48
|
+
4.times do |_i|
|
35
49
|
threads << Thread.new do
|
36
50
|
times_per_thread.times do
|
37
|
-
split_client.get_treatment user_id, feature_id,
|
51
|
+
split_client.get_treatment user_id, feature_id, attr: 123
|
38
52
|
end
|
39
53
|
end
|
40
54
|
end
|
41
55
|
threads.map(&:join)
|
42
|
-
|
56
|
+
end
|
43
57
|
end
|
data/tasks/irb.rake
CHANGED
@@ -1,4 +1,6 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
desc 'Open an irb session preloaded with this library'
|
2
4
|
task :irb do
|
3
|
-
sh
|
4
|
-
end
|
5
|
+
sh 'irb -rubygems -I lib -r splitclient-rb.rb'
|
6
|
+
end
|
data/tasks/rspec.rake
CHANGED