splitclient-rb 5.1.3.pre.rc4-java → 5.1.4.pre.rc1-java
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +1 -3
- data/Detailed-README.md +12 -21
- data/exe/splitio +96 -0
- data/lib/splitclient-rb/cache/adapters/redis_adapter.rb +5 -11
- data/lib/splitclient-rb/cache/repositories/impressions/memory_repository.rb +20 -22
- data/lib/splitclient-rb/cache/repositories/impressions/redis_repository.rb +51 -29
- data/lib/splitclient-rb/cache/repositories/impressions_repository.rb +6 -34
- data/lib/splitclient-rb/cache/senders/events_sender.rb +1 -7
- data/lib/splitclient-rb/cache/senders/impressions_formatter.rb +24 -31
- data/lib/splitclient-rb/cache/senders/impressions_sender.rb +3 -5
- data/lib/splitclient-rb/cache/senders/metrics_sender.rb +3 -5
- data/lib/splitclient-rb/cache/stores/segment_store.rb +1 -1
- data/lib/splitclient-rb/cache/stores/split_store.rb +1 -7
- data/lib/splitclient-rb/clients/split_client.rb +7 -6
- data/lib/splitclient-rb/engine/api/client.rb +2 -1
- data/lib/splitclient-rb/engine/api/events.rb +12 -13
- data/lib/splitclient-rb/engine/api/impressions.rb +11 -12
- data/lib/splitclient-rb/engine/api/metrics.rb +10 -10
- data/lib/splitclient-rb/engine/parser/evaluator.rb +1 -1
- data/lib/splitclient-rb/engine/parser/split_adapter.rb +21 -16
- data/lib/splitclient-rb/split_config.rb +1 -1
- data/lib/splitclient-rb/split_factory.rb +0 -31
- data/lib/splitclient-rb/validators.rb +23 -27
- data/lib/splitclient-rb/version.rb +1 -1
- data/splitclient-rb.gemspec +3 -1
- data/splitio.yml.example +7 -0
- metadata +11 -8
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0a45f8a3640a0089cccadfe8cc6bbeb3b21f7d57
|
4
|
+
data.tar.gz: dfcfabfd547fc59bdd4884a23133f89721f2a605
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f7fe35021e61db088ef74c6bb0b6ab8da7deff8e6a88b22c265c3ff2dd8cbbbd9db21871e70dd3cdc4abfa35743503a6d806789f9e3f475a8de7e7b612fdd28e
|
7
|
+
data.tar.gz: 594ee2a4ffa7cbe7f4d0bbad4fedc4a60e9c033d749c0ca1c019c6434de95dd2873969560ad92d15dd2f738e36e087847017f3b8a515f5adf43b4d3e77416a85
|
data/.rubocop.yml
CHANGED
data/Detailed-README.md
CHANGED
@@ -72,17 +72,6 @@ else
|
|
72
72
|
end
|
73
73
|
```
|
74
74
|
|
75
|
-
**Note**: You can ensure the SDK resources are loaded before querying for treatments by using `block_until_ready`. See [Advanced Configuration](#advanced-configuration).
|
76
|
-
``` ruby
|
77
|
-
options = {
|
78
|
-
block_until_ready: 10
|
79
|
-
}
|
80
|
-
|
81
|
-
# Then init the factory passing the options hash
|
82
|
-
factory = SplitIoClient::SplitFactoryBuilder.build('YOUR_API_KEY', options)
|
83
|
-
split_client = factory.client
|
84
|
-
```
|
85
|
-
|
86
75
|
For features that use targeting rules based on user attributes, you can call the `get_treatment` method the following way:
|
87
76
|
|
88
77
|
```ruby
|
@@ -250,7 +239,7 @@ The following values can be customized:
|
|
250
239
|
|
251
240
|
*default value* = `60`
|
252
241
|
|
253
|
-
**impressions_queue_size** : The size of the impressions queue in case of `cache_adapter == :memory`.
|
242
|
+
**impressions_queue_size** : The size of the impressions queue in case of `cache_adapter == :memory`.
|
254
243
|
|
255
244
|
*default value* = 5000
|
256
245
|
|
@@ -258,10 +247,6 @@ The following values can be customized:
|
|
258
247
|
|
259
248
|
*default value* = defaults to `impressions_queue_size`
|
260
249
|
|
261
|
-
**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.
|
262
|
-
|
263
|
-
*default value* = 500
|
264
|
-
|
265
250
|
**debug_enabled** : Enables extra logging (verbose mode).
|
266
251
|
|
267
252
|
*default value* = `false`
|
@@ -344,9 +329,15 @@ options = {
|
|
344
329
|
|
345
330
|
```ruby
|
346
331
|
options = {
|
347
|
-
|
332
|
+
connection_timeout: 10,
|
333
|
+
read_timeout: 5,
|
334
|
+
features_refresh_rate: 120,
|
335
|
+
segments_refresh_rate: 120,
|
336
|
+
metrics_refresh_rate: 360,
|
337
|
+
impressions_refresh_rate: 360,
|
338
|
+
logger: Logger.new('logfile.log'),
|
348
339
|
cache_adapter: :redis,
|
349
|
-
mode: :
|
340
|
+
mode: :standalone,
|
350
341
|
redis_url: 'redis://127.0.0.1:6379/0'
|
351
342
|
}
|
352
343
|
begin
|
@@ -397,10 +388,10 @@ In the example above, the listener simply takes an impression and logs it to the
|
|
397
388
|
|
398
389
|
The SDK is capable of running in two different modes to fit in different infrastructure configurations:
|
399
390
|
|
400
|
-
- `:standalone` - (default) : The SDK will retrieve information (e.g. split definitions) periodically from the Split servers, and store it in the memory
|
401
|
-
- `: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.
|
391
|
+
- `: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.
|
392
|
+
- `: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.
|
402
393
|
|
403
|
-
_You can choose between these 2 modes setting the `mode` option in the config.
|
394
|
+
_You can choose between these 2 modes setting the `mode` option in the config._
|
404
395
|
|
405
396
|
## SDK Server Compatibility
|
406
397
|
|
data/exe/splitio
ADDED
@@ -0,0 +1,96 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
lib = File.expand_path('../lib', __dir__)
|
5
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
6
|
+
|
7
|
+
require 'optparse'
|
8
|
+
require 'yaml'
|
9
|
+
require_relative '../lib/splitclient-rb'
|
10
|
+
|
11
|
+
# ARGV << '-h' if ARGV.empty?
|
12
|
+
|
13
|
+
config_path = ''
|
14
|
+
options = {}
|
15
|
+
opt_parser = OptionParser.new do |opts|
|
16
|
+
opts.banner = 'Usage: splitio [options]'
|
17
|
+
|
18
|
+
opts.on('-cPATH', '--config=PATH', 'Set the path to splitio.yml config file') do |c|
|
19
|
+
config_path = c
|
20
|
+
end
|
21
|
+
|
22
|
+
opts.on('--base-uri=BASE_URI', 'Set the base uri for Split SDK') do |c|
|
23
|
+
options[:base_uri] = c
|
24
|
+
end
|
25
|
+
|
26
|
+
opts.on('--events-uri=EVENTS_URI', 'Set the events uri for Split SDK') do |c|
|
27
|
+
options[:events_uri] = c
|
28
|
+
end
|
29
|
+
|
30
|
+
opts.on('--api-key=API_KEY', 'Set the API Key for Split SDK') do |c|
|
31
|
+
options[:api_key] = c
|
32
|
+
end
|
33
|
+
|
34
|
+
opts.on('--read-timeout=READ_TIMEOUT', 'Read timeout in seconds') do |c|
|
35
|
+
options[:read_timeout] = c
|
36
|
+
end
|
37
|
+
|
38
|
+
opts.on('--connection-timeout=CONNECTION_TIMEOUT', 'Connection timeout in seconds') do |c|
|
39
|
+
options[:connection_timeout] = c
|
40
|
+
end
|
41
|
+
|
42
|
+
opts.on('--features-refresh-rate=FEATURES_REFRESH_RATE', 'Features refresh rate in seconds') do |c|
|
43
|
+
options[:features_refresh_rate] = c
|
44
|
+
end
|
45
|
+
|
46
|
+
opts.on('--segments-refresh-rate=SEGMENTS_REFRESH_RATE', 'Segments refresh rate in seconds') do |c|
|
47
|
+
options[:segments_refresh_rate] = c
|
48
|
+
end
|
49
|
+
|
50
|
+
opts.on('--metrics-refresh-rate=METRICS_REFRESH_RATE', 'Metrics refresh rate in seconds') do |c|
|
51
|
+
options[:metrics_refresh_rate] = c
|
52
|
+
end
|
53
|
+
|
54
|
+
opts.on('--impressions-refresh-rate=IMPRESSIONS_REFRESH_RATE', 'Impressions refresh rate in seconds') do |c|
|
55
|
+
options[:impressions_refresh_rate] = c
|
56
|
+
end
|
57
|
+
|
58
|
+
opts.on('--ready=SECONDS', 'Seconds to block the app until SDK is ready or false to run in non-blocking mode') do |c|
|
59
|
+
options[:ready] = c
|
60
|
+
end
|
61
|
+
|
62
|
+
opts.on('--redis-url=REDIS_URL', 'Set base uri for Split SDK') do |c|
|
63
|
+
options[:redis_url] = c
|
64
|
+
end
|
65
|
+
|
66
|
+
opts.on('--transport-debug', 'Enable transport debug') do
|
67
|
+
options[:transport_debug_enabled] = true
|
68
|
+
end
|
69
|
+
|
70
|
+
opts.on('-d', '--debug', 'Enable debug mode') do
|
71
|
+
options[:debug_enabled] = true
|
72
|
+
end
|
73
|
+
|
74
|
+
opts.on_tail('-h', '--help', 'Prints this help') do
|
75
|
+
puts opts
|
76
|
+
exit
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
begin
|
81
|
+
opt_parser.parse!(ARGV)
|
82
|
+
rescue OptionParser::InvalidOption => e
|
83
|
+
puts e
|
84
|
+
puts opt_parser
|
85
|
+
exit(1)
|
86
|
+
end
|
87
|
+
|
88
|
+
config = config_path != '' ? YAML.load_file(config_path) : {}
|
89
|
+
config
|
90
|
+
.merge!(mode: :producer, cache_adapter: :redis)
|
91
|
+
.merge!(options)
|
92
|
+
.merge!(api_key: ENV['API_KEY'] || config[:api_key])
|
93
|
+
.merge!(base_uri: ENV['SDK_URI'] || config[:base_uri])[:events_uri] = ENV['EVENTS_URI'] || config[:events_uri]
|
94
|
+
# IDENTIFY_BASE_URI
|
95
|
+
|
96
|
+
SplitIoClient::SplitFactory.new(config[:api_key], config)
|
@@ -1,5 +1,3 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
1
|
require 'json'
|
4
2
|
|
5
3
|
module SplitIoClient
|
@@ -87,8 +85,8 @@ module SplitIoClient
|
|
87
85
|
end
|
88
86
|
|
89
87
|
# Set
|
90
|
-
|
91
|
-
|
88
|
+
alias_method :initialize_set, :initialize_map
|
89
|
+
alias_method :find_sets_by_prefix, :find_strings_by_prefix
|
92
90
|
|
93
91
|
def add_to_set(key, val)
|
94
92
|
@redis.sadd(key, val)
|
@@ -128,7 +126,7 @@ module SplitIoClient
|
|
128
126
|
def get_from_queue(key, count)
|
129
127
|
items = @redis.lrange(key, 0, count - 1)
|
130
128
|
fetched_count = items.size
|
131
|
-
items_to_remove = fetched_count == count ? count : fetched_count
|
129
|
+
items_to_remove = (fetched_count == count) ? count : fetched_count
|
132
130
|
|
133
131
|
@redis.ltrim(key, items_to_remove, -1)
|
134
132
|
|
@@ -150,9 +148,9 @@ module SplitIoClient
|
|
150
148
|
@redis.incrby(key, inc)
|
151
149
|
end
|
152
150
|
|
153
|
-
def pipelined
|
151
|
+
def pipelined(&block)
|
154
152
|
@redis.pipelined do
|
155
|
-
|
153
|
+
block.call
|
156
154
|
end
|
157
155
|
end
|
158
156
|
|
@@ -161,10 +159,6 @@ module SplitIoClient
|
|
161
159
|
|
162
160
|
keys.map { |key| @redis.del(key) }
|
163
161
|
end
|
164
|
-
|
165
|
-
def expire(key, seconds)
|
166
|
-
@redis.expire(key, seconds)
|
167
|
-
end
|
168
162
|
end
|
169
163
|
end
|
170
164
|
end
|
@@ -1,44 +1,42 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
1
|
module SplitIoClient
|
4
2
|
module Cache
|
5
3
|
module Repositories
|
6
4
|
module Impressions
|
7
|
-
class MemoryRepository
|
5
|
+
class MemoryRepository
|
6
|
+
|
8
7
|
def initialize(adapter)
|
9
8
|
@adapter = adapter
|
10
9
|
end
|
11
10
|
|
12
11
|
# Store impression data in the selected adapter
|
13
|
-
def add(
|
14
|
-
@adapter.add_to_queue(
|
15
|
-
m: metadata,
|
16
|
-
i: impression_data(
|
17
|
-
matching_key,
|
18
|
-
bucketing_key,
|
19
|
-
split_name,
|
20
|
-
treatment,
|
21
|
-
time
|
22
|
-
)
|
23
|
-
)
|
12
|
+
def add(split_name, data)
|
13
|
+
@adapter.add_to_queue(feature: split_name, impressions: data)
|
24
14
|
rescue ThreadError # queue is full
|
25
15
|
if random_sampler.rand(1..1000) <= 2 # log only 0.2 % of the time
|
26
|
-
SplitIoClient.configuration.logger.warn("Dropping impressions. Current size is \
|
27
|
-
|
28
|
-
'Consider increasing impressions_queue_size')
|
16
|
+
SplitIoClient.configuration.logger.warn("Dropping impressions. Current size is #{SplitIoClient.configuration.impressions_queue_size}. " \
|
17
|
+
"Consider increasing impressions_queue_size")
|
29
18
|
end
|
30
19
|
end
|
31
20
|
|
32
21
|
def add_bulk(key, bucketing_key, treatments, time)
|
33
22
|
treatments.each do |split_name, treatment|
|
34
|
-
add(
|
23
|
+
add(
|
24
|
+
split_name,
|
25
|
+
'keyName' => key,
|
26
|
+
'bucketingKey' => bucketing_key,
|
27
|
+
'treatment' => treatment[:treatment],
|
28
|
+
'label' => SplitIoClient.configuration.labels_enabled ? treatment[:label] : nil,
|
29
|
+
'changeNumber' => treatment[:change_number],
|
30
|
+
'time' => time
|
31
|
+
)
|
35
32
|
end
|
36
33
|
end
|
37
34
|
|
38
|
-
def
|
39
|
-
return [] if SplitIoClient.configuration.impressions_bulk_size
|
40
|
-
|
41
|
-
|
35
|
+
def get_batch
|
36
|
+
return [] if SplitIoClient.configuration.impressions_bulk_size == 0
|
37
|
+
@adapter.get_batch(SplitIoClient.configuration.impressions_bulk_size).map do |impression|
|
38
|
+
impression.update(ip: SplitIoClient.configuration.machine_ip)
|
39
|
+
end
|
42
40
|
end
|
43
41
|
|
44
42
|
private
|
@@ -1,53 +1,75 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
1
|
module SplitIoClient
|
4
2
|
module Cache
|
5
3
|
module Repositories
|
6
4
|
module Impressions
|
7
|
-
class RedisRepository <
|
8
|
-
EXPIRE_SECONDS = 3600
|
5
|
+
class RedisRepository < Repository
|
9
6
|
|
10
7
|
def initialize(adapter)
|
11
8
|
@adapter = adapter
|
12
9
|
end
|
13
10
|
|
14
|
-
|
15
|
-
|
11
|
+
# Store impression data in Redis
|
12
|
+
def add(split_name, data)
|
13
|
+
@adapter.add_to_set(
|
14
|
+
impressions_metrics_key("impressions.#{split_name}"),
|
15
|
+
data.to_json
|
16
|
+
)
|
16
17
|
end
|
17
18
|
|
18
|
-
def add_bulk(
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
}.to_json
|
19
|
+
def add_bulk(key, bucketing_key, treatments, time)
|
20
|
+
@adapter.redis.pipelined do
|
21
|
+
treatments.each do |split_name, treatment|
|
22
|
+
add(split_name,
|
23
|
+
'keyName' => key,
|
24
|
+
'bucketingKey' => bucketing_key,
|
25
|
+
'treatment' => treatment[:treatment],
|
26
|
+
'label' => SplitIoClient.configuration.labels_enabled ? treatment[:label] : nil,
|
27
|
+
'changeNumber' => treatment[:change_number],
|
28
|
+
'time' => time)
|
29
|
+
end
|
30
30
|
end
|
31
|
+
end
|
31
32
|
|
32
|
-
|
33
|
+
# Get random impressions from redis in batches of size SplitIoClient.configuration.impressions_bulk_size,
|
34
|
+
# delete fetched impressions afterwards
|
35
|
+
def get_batch
|
36
|
+
impressions = impression_keys.each_with_object([]) do |key, memo|
|
37
|
+
ip = key.split('/')[-2] # 'prefix/sdk_lang/ip/impressions.name' -> ip
|
38
|
+
if ip.nil?
|
39
|
+
SplitIoClient.configuration.logger.warn("Impressions IP parse error for key: #{key}")
|
40
|
+
next
|
41
|
+
end
|
42
|
+
split_name = key.split('.').last
|
43
|
+
members = @adapter.random_set_elements(key, SplitIoClient.configuration.impressions_bulk_size)
|
44
|
+
members.each do |impression|
|
45
|
+
parsed_impression = JSON.parse(impression)
|
33
46
|
|
34
|
-
|
35
|
-
|
36
|
-
|
47
|
+
memo << {
|
48
|
+
feature: split_name.to_sym,
|
49
|
+
impressions: parsed_impression,
|
50
|
+
ip: ip
|
51
|
+
}
|
52
|
+
end
|
53
|
+
|
54
|
+
@adapter.delete_from_set(key, members)
|
37
55
|
|
38
|
-
def batch
|
39
|
-
@adapter.get_from_queue(key, SplitIoClient.configuration.impressions_bulk_size).map do |e|
|
40
|
-
impression = JSON.parse(e, symbolize_names: true)
|
41
|
-
impression[:i][:f] = impression[:i][:f].to_sym
|
42
|
-
impression
|
43
56
|
end
|
57
|
+
impressions
|
44
58
|
rescue StandardError => e
|
45
59
|
SplitIoClient.configuration.logger.error("Exception while clearing impressions cache: #{e}")
|
60
|
+
|
46
61
|
[]
|
47
62
|
end
|
48
63
|
|
49
|
-
|
50
|
-
|
64
|
+
private
|
65
|
+
|
66
|
+
# Get all sets by prefix
|
67
|
+
def impression_keys
|
68
|
+
@adapter.find_sets_by_prefix("#{SplitIoClient.configuration.redis_namespace}/*/impressions.*")
|
69
|
+
rescue StandardError => e
|
70
|
+
SplitIoClient.configuration.logger.error("Exception while fetching impression_keys: #{e}")
|
71
|
+
|
72
|
+
[]
|
51
73
|
end
|
52
74
|
end
|
53
75
|
end
|
@@ -1,46 +1,18 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
1
|
module SplitIoClient
|
4
2
|
module Cache
|
5
3
|
module Repositories
|
6
4
|
# Repository which forwards impressions interface to the selected adapter
|
7
5
|
class ImpressionsRepository < Repository
|
8
6
|
extend Forwardable
|
9
|
-
def_delegators :@adapter, :add, :add_bulk, :
|
7
|
+
def_delegators :@adapter, :add, :add_bulk, :get_batch, :empty?
|
10
8
|
|
11
9
|
def initialize(adapter)
|
12
10
|
@adapter = case adapter.class.to_s
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
end
|
19
|
-
|
20
|
-
protected
|
21
|
-
|
22
|
-
def impression_data(matching_key, bucketing_key, split_name, treatment, timestamp)
|
23
|
-
{
|
24
|
-
k: matching_key,
|
25
|
-
b: bucketing_key,
|
26
|
-
f: split_name,
|
27
|
-
t: treatment[:treatment],
|
28
|
-
r: applied_rule(treatment[:label]),
|
29
|
-
c: treatment[:change_number],
|
30
|
-
m: timestamp
|
31
|
-
}
|
32
|
-
end
|
33
|
-
|
34
|
-
def metadata
|
35
|
-
{
|
36
|
-
s: "#{SplitIoClient.configuration.language}-#{SplitIoClient.configuration.version}",
|
37
|
-
i: SplitIoClient.configuration.machine_ip,
|
38
|
-
n: SplitIoClient.configuration.machine_name
|
39
|
-
}
|
40
|
-
end
|
41
|
-
|
42
|
-
def applied_rule(label)
|
43
|
-
SplitIoClient.configuration.labels_enabled ? label : nil
|
11
|
+
when 'SplitIoClient::Cache::Adapters::MemoryAdapter'
|
12
|
+
Repositories::Impressions::MemoryRepository.new(adapter)
|
13
|
+
when 'SplitIoClient::Cache::Adapters::RedisAdapter'
|
14
|
+
Repositories::Impressions::RedisRepository.new(adapter)
|
15
|
+
end
|
44
16
|
end
|
45
17
|
end
|
46
18
|
end
|
@@ -1,5 +1,3 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
1
|
module SplitIoClient
|
4
2
|
module Cache
|
5
3
|
module Senders
|
@@ -38,14 +36,10 @@ module SplitIoClient
|
|
38
36
|
end
|
39
37
|
|
40
38
|
def post_events
|
41
|
-
|
39
|
+
SplitIoClient::Api::Events.new(@api_key, @events_repository.clear).post
|
42
40
|
rescue StandardError => error
|
43
41
|
SplitIoClient.configuration.log_found_exception(__method__.to_s, error)
|
44
42
|
end
|
45
|
-
|
46
|
-
def events_api
|
47
|
-
@events_api ||= SplitIoClient::Api::Events.new(@api_key)
|
48
|
-
end
|
49
43
|
end
|
50
44
|
end
|
51
45
|
end
|
@@ -1,5 +1,3 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
1
|
module SplitIoClient
|
4
2
|
module Cache
|
5
3
|
module Senders
|
@@ -9,15 +7,29 @@ module SplitIoClient
|
|
9
7
|
end
|
10
8
|
|
11
9
|
def call(raw_impressions)
|
12
|
-
impressions = raw_impressions
|
10
|
+
impressions = raw_impressions ? raw_impressions : @impressions_repository.get_batch
|
11
|
+
formatted_impressions = []
|
13
12
|
filtered_impressions = filter_impressions(impressions)
|
14
13
|
|
15
14
|
return [] if impressions.empty? || filtered_impressions.empty?
|
16
15
|
|
17
16
|
formatted_impressions = unique_features(filtered_impressions).each_with_object([]) do |feature, memo|
|
18
|
-
|
19
|
-
|
20
|
-
|
17
|
+
ip = nil
|
18
|
+
current_impressions =
|
19
|
+
filtered_impressions
|
20
|
+
.select { |impression| impression[:feature] == feature }
|
21
|
+
.map do |impression|
|
22
|
+
ip = impression[:ip]
|
23
|
+
{
|
24
|
+
keyName: impression[:impressions]['keyName'] || impression[:impressions]['key_name'],
|
25
|
+
treatment: impression[:impressions]['treatment'],
|
26
|
+
time: impression[:impressions]['time'],
|
27
|
+
bucketingKey: impression[:impressions]['bucketingKey'] || impression[:impressions]['bucketing_key'],
|
28
|
+
label: impression[:impressions]['label'],
|
29
|
+
changeNumber: impression[:impressions]['changeNumber'] || impression[:impressions]['change_number'],
|
30
|
+
}
|
31
|
+
end
|
32
|
+
|
21
33
|
memo << {
|
22
34
|
testName: feature.to_sym,
|
23
35
|
keyImpressions: current_impressions,
|
@@ -30,27 +42,8 @@ module SplitIoClient
|
|
30
42
|
|
31
43
|
private
|
32
44
|
|
33
|
-
def feature_impressions(filtered_impressions, feature)
|
34
|
-
filtered_impressions.select do |impression|
|
35
|
-
impression[:i][:f] == feature
|
36
|
-
end
|
37
|
-
end
|
38
|
-
|
39
|
-
def current_impressions(feature_impressions)
|
40
|
-
feature_impressions.map do |impression|
|
41
|
-
{
|
42
|
-
keyName: impression[:i][:k],
|
43
|
-
treatment: impression[:i][:t],
|
44
|
-
time: impression[:i][:m],
|
45
|
-
bucketingKey: impression[:i][:b],
|
46
|
-
label: impression[:i][:r],
|
47
|
-
changeNumber: impression[:i][:c]
|
48
|
-
}
|
49
|
-
end
|
50
|
-
end
|
51
|
-
|
52
45
|
def unique_features(impressions)
|
53
|
-
impressions.map { |impression| impression[:
|
46
|
+
impressions.map { |impression| impression[:feature] }.uniq
|
54
47
|
end
|
55
48
|
|
56
49
|
# Filter seen impressions by impression_hash
|
@@ -68,11 +61,11 @@ module SplitIoClient
|
|
68
61
|
end
|
69
62
|
|
70
63
|
def impression_hash(impression)
|
71
|
-
"#{impression[:
|
72
|
-
"#{impression[:
|
73
|
-
"#{impression[:
|
74
|
-
"#{impression[:
|
75
|
-
"#{impression[:
|
64
|
+
"#{impression[:feature]}:" \
|
65
|
+
"#{impression[:impressions]['keyName']}:" \
|
66
|
+
"#{impression[:impressions]['bucketingKey']}:" \
|
67
|
+
"#{impression[:impressions]['changeNumber']}:" \
|
68
|
+
"#{impression[:impressions]['treatment']}"
|
76
69
|
end
|
77
70
|
end
|
78
71
|
end
|
@@ -1,5 +1,3 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
1
|
module SplitIoClient
|
4
2
|
module Cache
|
5
3
|
module Senders
|
@@ -49,7 +47,7 @@ module SplitIoClient
|
|
49
47
|
end
|
50
48
|
|
51
49
|
def post_impressions
|
52
|
-
|
50
|
+
impressions_client.post
|
53
51
|
rescue StandardError => error
|
54
52
|
SplitIoClient.configuration.log_found_exception(__method__.to_s, error)
|
55
53
|
end
|
@@ -58,8 +56,8 @@ module SplitIoClient
|
|
58
56
|
ImpressionsFormatter.new(@impressions_repository).call(raw_impressions)
|
59
57
|
end
|
60
58
|
|
61
|
-
def
|
62
|
-
|
59
|
+
def impressions_client
|
60
|
+
SplitIoClient::Api::Impressions.new(@api_key, formatted_impressions)
|
63
61
|
end
|
64
62
|
end
|
65
63
|
end
|
@@ -1,5 +1,3 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
1
|
module SplitIoClient
|
4
2
|
module Cache
|
5
3
|
module Senders
|
@@ -36,13 +34,13 @@ module SplitIoClient
|
|
36
34
|
end
|
37
35
|
|
38
36
|
def post_metrics
|
39
|
-
|
37
|
+
metrics_client.post
|
40
38
|
rescue StandardError => error
|
41
39
|
SplitIoClient.configuration.log_found_exception(__method__.to_s, error)
|
42
40
|
end
|
43
41
|
|
44
|
-
def
|
45
|
-
|
42
|
+
def metrics_client
|
43
|
+
SplitIoClient::Api::Metrics.new(@api_key, @metrics_repository)
|
46
44
|
end
|
47
45
|
end
|
48
46
|
end
|
@@ -66,7 +66,7 @@ module SplitIoClient
|
|
66
66
|
end
|
67
67
|
|
68
68
|
def splits_since(since)
|
69
|
-
|
69
|
+
SplitIoClient::Api::Splits.new(@api_key, @metrics).since(since)
|
70
70
|
end
|
71
71
|
|
72
72
|
def add_split_unless_archived(split)
|
@@ -90,12 +90,6 @@ module SplitIoClient
|
|
90
90
|
|
91
91
|
@splits_repository.add_split(split)
|
92
92
|
end
|
93
|
-
|
94
|
-
private
|
95
|
-
|
96
|
-
def splits_api
|
97
|
-
@splits_api ||= SplitIoClient::Api::Splits.new(@api_key, @metrics)
|
98
|
-
end
|
99
93
|
end
|
100
94
|
end
|
101
95
|
end
|
@@ -136,12 +136,13 @@ module SplitIoClient
|
|
136
136
|
|
137
137
|
return if SplitIoClient.configuration.disable_impressions || !store_impressions
|
138
138
|
|
139
|
-
@impressions_repository.add(
|
140
|
-
matching_key,
|
141
|
-
bucketing_key,
|
142
|
-
|
143
|
-
treatment,
|
144
|
-
time
|
139
|
+
@impressions_repository.add(split_name,
|
140
|
+
'keyName' => matching_key,
|
141
|
+
'bucketingKey' => bucketing_key,
|
142
|
+
'treatment' => treatment[:treatment],
|
143
|
+
'label' => SplitIoClient.configuration.labels_enabled ? treatment[:label] : nil,
|
144
|
+
'time' => time,
|
145
|
+
'changeNumber' => treatment[:change_number]
|
145
146
|
)
|
146
147
|
|
147
148
|
route_impression(split_name, matching_key, bucketing_key, time, treatment, attributes)
|
@@ -38,7 +38,8 @@ module SplitIoClient
|
|
38
38
|
end
|
39
39
|
rescue StandardError => e
|
40
40
|
SplitIoClient.configuration.logger.warn("#{e}\nURL:#{url}\ndata:#{data}\nparams:#{params}")
|
41
|
-
|
41
|
+
|
42
|
+
false
|
42
43
|
end
|
43
44
|
|
44
45
|
private
|
@@ -1,32 +1,31 @@
|
|
1
1
|
module SplitIoClient
|
2
2
|
module Api
|
3
3
|
class Events < Client
|
4
|
-
def initialize(api_key)
|
4
|
+
def initialize(api_key, events)
|
5
5
|
@api_key = api_key
|
6
|
+
@events = events
|
6
7
|
end
|
7
8
|
|
8
|
-
def post
|
9
|
-
if events.empty?
|
9
|
+
def post
|
10
|
+
if @events.empty?
|
10
11
|
SplitIoClient.configuration.logger.debug('No events to report') if SplitIoClient.configuration.debug_enabled
|
11
12
|
return
|
12
13
|
end
|
13
14
|
|
14
|
-
events.each_slice(SplitIoClient.configuration.events_queue_size) do |
|
15
|
+
@events.each_slice(SplitIoClient.configuration.events_queue_size) do |event_slice|
|
15
16
|
result = post_api(
|
16
17
|
"#{SplitIoClient.configuration.events_uri}/events/bulk",
|
17
18
|
@api_key,
|
18
|
-
|
19
|
-
'SplitSDKMachineIP' =>
|
20
|
-
'SplitSDKMachineName' =>
|
21
|
-
'SplitSDKVersion' =>
|
19
|
+
event_slice.map { |event| formatted_event(event[:e]) },
|
20
|
+
'SplitSDKMachineIP' => event_slice[0][:m][:i],
|
21
|
+
'SplitSDKMachineName' => event_slice[0][:m][:n],
|
22
|
+
'SplitSDKVersion' => event_slice[0][:m][:s]
|
22
23
|
)
|
23
24
|
|
24
|
-
if
|
25
|
-
|
25
|
+
if (200..299).include? result.status
|
26
|
+
SplitIoClient.configuration.logger.debug("Events reported: #{event_slice.size}") if SplitIoClient.configuration.debug_enabled
|
26
27
|
else
|
27
|
-
|
28
|
-
" - Check your API key and base URI")
|
29
|
-
raise 'Split SDK failed to connect to backend to post events'
|
28
|
+
SplitIoClient.configuration.logger.error("Unexpected status code while posting events: #{result.status}")
|
30
29
|
end
|
31
30
|
end
|
32
31
|
end
|
@@ -1,25 +1,24 @@
|
|
1
1
|
module SplitIoClient
|
2
2
|
module Api
|
3
3
|
class Impressions < Client
|
4
|
-
def initialize(api_key)
|
4
|
+
def initialize(api_key, impressions)
|
5
5
|
@api_key = api_key
|
6
|
+
@impressions = impressions
|
6
7
|
end
|
7
8
|
|
8
|
-
def post
|
9
|
-
if impressions.empty?
|
9
|
+
def post
|
10
|
+
if @impressions.empty?
|
10
11
|
SplitIoClient.configuration.logger.debug('No impressions to report') if SplitIoClient.configuration.debug_enabled
|
11
12
|
return
|
12
13
|
end
|
13
14
|
|
14
|
-
impressions_by_ip
|
15
|
-
result = post_api("#{SplitIoClient.configuration.events_uri}/testImpressions/bulk", @api_key,
|
15
|
+
impressions_by_ip.each do |ip, impressions|
|
16
|
+
result = post_api("#{SplitIoClient.configuration.events_uri}/testImpressions/bulk", @api_key, impressions, 'SplitSDKMachineIP' => ip)
|
16
17
|
|
17
|
-
if
|
18
|
-
|
18
|
+
if (200..299).include? result.status
|
19
|
+
SplitIoClient.configuration.logger.debug("Impressions reported: #{total_impressions(@impressions)}") if SplitIoClient.configuration.debug_enabled
|
19
20
|
else
|
20
|
-
|
21
|
-
" - Check your API key and base URI")
|
22
|
-
raise 'Split SDK failed to connect to backend to post impressions'
|
21
|
+
SplitIoClient.configuration.logger.error("Unexpected status code while posting impressions: #{result.status}")
|
23
22
|
end
|
24
23
|
end
|
25
24
|
end
|
@@ -34,8 +33,8 @@ module SplitIoClient
|
|
34
33
|
|
35
34
|
private
|
36
35
|
|
37
|
-
def impressions_by_ip
|
38
|
-
impressions.group_by { |impression| impression[:ip] }
|
36
|
+
def impressions_by_ip
|
37
|
+
@impressions.group_by { |impression| impression[:ip] }
|
39
38
|
end
|
40
39
|
end
|
41
40
|
end
|
@@ -20,9 +20,9 @@ module SplitIoClient
|
|
20
20
|
@metrics_repository.latencies.each do |name, latencies|
|
21
21
|
metrics_time = { name: name, latencies: latencies }
|
22
22
|
|
23
|
-
|
23
|
+
result = post_api("#{SplitIoClient.configuration.events_uri}/metrics/time", @api_key, metrics_time)
|
24
24
|
|
25
|
-
log_status(
|
25
|
+
log_status(result, metrics_time.size)
|
26
26
|
end
|
27
27
|
end
|
28
28
|
|
@@ -36,9 +36,9 @@ module SplitIoClient
|
|
36
36
|
@metrics_repository.counts.each do |name, count|
|
37
37
|
metrics_count = { name: name, delta: count }
|
38
38
|
|
39
|
-
|
39
|
+
result = post_api("#{SplitIoClient.configuration.events_uri}/metrics/counter", @api_key, metrics_count)
|
40
40
|
|
41
|
-
log_status(
|
41
|
+
log_status(result, metrics_count.size)
|
42
42
|
end
|
43
43
|
end
|
44
44
|
@metrics_repository.clear_counts
|
@@ -46,13 +46,13 @@ module SplitIoClient
|
|
46
46
|
|
47
47
|
private
|
48
48
|
|
49
|
-
def log_status(
|
50
|
-
if
|
51
|
-
|
49
|
+
def log_status(result, info_to_log)
|
50
|
+
if result == false
|
51
|
+
SplitIoClient.configuration.logger.error("Failed to make a http request")
|
52
|
+
elsif (200..299).include? result.status
|
53
|
+
SplitIoClient.configuration.logger.debug("Metric time reported: #{info_to_log}") if SplitIoClient.configuration.debug_enabled
|
52
54
|
else
|
53
|
-
|
54
|
-
" - Check your API key and base URI")
|
55
|
-
raise 'Split SDK failed to connect to backend to post metrics'
|
55
|
+
SplitIoClient.configuration.logger.error("Unexpected status code while posting time metrics: #{result.status}")
|
56
56
|
end
|
57
57
|
end
|
58
58
|
end
|
@@ -51,7 +51,7 @@ module SplitIoClient
|
|
51
51
|
if split[:trafficAllocation] < 100
|
52
52
|
bucket = splitter.bucket(splitter.count_hash(key, split[:trafficAllocationSeed].to_i, legacy_algo))
|
53
53
|
|
54
|
-
if bucket
|
54
|
+
if bucket >= split[:trafficAllocation]
|
55
55
|
return treatment_hash(Models::Label::NOT_IN_SPLIT, split[:defaultTreatment], split[:changeNumber])
|
56
56
|
end
|
57
57
|
end
|
@@ -24,15 +24,7 @@ module SplitIoClient
|
|
24
24
|
# @param sdk_blocker [SDKBlocker] SDKBlocker instance which blocks splits_repository/segments_repository
|
25
25
|
#
|
26
26
|
# @return [SplitIoClient] split.io client instance
|
27
|
-
def initialize(
|
28
|
-
api_key,
|
29
|
-
splits_repository,
|
30
|
-
segments_repository,
|
31
|
-
impressions_repository,
|
32
|
-
metrics_repository,
|
33
|
-
events_repository,
|
34
|
-
sdk_blocker
|
35
|
-
)
|
27
|
+
def initialize(api_key, splits_repository, segments_repository, impressions_repository, metrics_repository, events_repository, sdk_blocker)
|
36
28
|
@api_key = api_key
|
37
29
|
@splits_repository = splits_repository
|
38
30
|
@segments_repository = segments_repository
|
@@ -42,15 +34,28 @@ module SplitIoClient
|
|
42
34
|
@metrics = Metrics.new(100, @metrics_repository)
|
43
35
|
@sdk_blocker = sdk_blocker
|
44
36
|
|
45
|
-
|
37
|
+
start_based_on_mode(SplitIoClient.configuration.mode)
|
46
38
|
end
|
47
39
|
|
48
|
-
def
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
40
|
+
def start_based_on_mode(mode)
|
41
|
+
case mode
|
42
|
+
when :standalone
|
43
|
+
split_store
|
44
|
+
segment_store
|
45
|
+
metrics_sender
|
46
|
+
impressions_sender
|
47
|
+
events_sender
|
48
|
+
when :consumer
|
49
|
+
# Do nothing in background
|
50
|
+
when :producer
|
51
|
+
split_store
|
52
|
+
segment_store
|
53
|
+
impressions_sender
|
54
|
+
metrics_sender
|
55
|
+
events_sender
|
56
|
+
|
57
|
+
sleep unless ENV['SPLITCLIENT_ENV'] == 'test'
|
58
|
+
end
|
54
59
|
end
|
55
60
|
|
56
61
|
# Starts thread which loops constantly and stores splits in the splits_repository of choice
|
@@ -109,7 +109,7 @@ module SplitIoClient
|
|
109
109
|
#
|
110
110
|
# The mode SDK will run
|
111
111
|
#
|
112
|
-
# @return [Symbol] One of the available SDK modes: standalone, consumer
|
112
|
+
# @return [Symbol] One of the available SDK modes: standalone, consumer, producer
|
113
113
|
attr_accessor :mode
|
114
114
|
|
115
115
|
# The read timeout for network connections in seconds.
|
@@ -8,9 +8,6 @@ module SplitIoClient
|
|
8
8
|
def initialize(api_key, config_hash = {})
|
9
9
|
@api_key = api_key
|
10
10
|
SplitIoClient.configure(config_hash)
|
11
|
-
|
12
|
-
raise 'Invalid SDK mode' unless valid_mode
|
13
|
-
|
14
11
|
@cache_adapter = SplitIoClient.configuration.cache_adapter
|
15
12
|
|
16
13
|
@splits_repository = SplitsRepository.new(@cache_adapter)
|
@@ -36,34 +33,6 @@ module SplitIoClient
|
|
36
33
|
SplitIoClient.configuration.threads.each { |_, t| t.exit }
|
37
34
|
end
|
38
35
|
|
39
|
-
def valid_mode
|
40
|
-
valid_startup_mode = false
|
41
|
-
case SplitIoClient.configuration.mode
|
42
|
-
when :consumer
|
43
|
-
if SplitIoClient.configuration.cache_adapter.is_a? SplitIoClient::Cache::Adapters::RedisAdapter
|
44
|
-
valid_startup_mode = true
|
45
|
-
else
|
46
|
-
SplitIoClient.configuration.logger.error('Consumer mode cannot be used with Memory adapter. ' \
|
47
|
-
'Use Redis adapter instead.')
|
48
|
-
end
|
49
|
-
when :standalone
|
50
|
-
if SplitIoClient.configuration.cache_adapter.is_a? SplitIoClient::Cache::Adapters::MemoryAdapter
|
51
|
-
valid_startup_mode = true
|
52
|
-
else
|
53
|
-
SplitIoClient.configuration.logger.error('Standalone mode cannot be used with Redis adapter. ' \
|
54
|
-
'Use Memory adapter instead.')
|
55
|
-
end
|
56
|
-
when :producer
|
57
|
-
SplitIoClient.configuration.logger.error('Producer mode is no longer supported. Use Split Synchronizer. ' \
|
58
|
-
'See: https://github.com/splitio/split-synchronizer')
|
59
|
-
else
|
60
|
-
SplitIoClient.configuration.logger.error('Invalid SDK mode selected. ' \
|
61
|
-
"Valid modes are 'standalone with memory adapter' and 'consumer with redis adapter'")
|
62
|
-
end
|
63
|
-
|
64
|
-
valid_startup_mode
|
65
|
-
end
|
66
|
-
|
67
36
|
alias resume! start!
|
68
37
|
end
|
69
38
|
end
|
@@ -1,14 +1,9 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
1
|
module SplitIoClient
|
4
2
|
module Validators
|
5
3
|
extend self
|
6
4
|
|
7
5
|
def valid_get_treatment_parameters(key, split_name, matching_key, bucketing_key)
|
8
|
-
valid_key?(key) &&
|
9
|
-
valid_split_name?(split_name) &&
|
10
|
-
valid_matching_key?(matching_key) &&
|
11
|
-
valid_bucketing_key?(key, bucketing_key)
|
6
|
+
valid_key?(key) && valid_split_name?(split_name) && valid_matching_key?(matching_key) && valid_bucketing_key?(bucketing_key)
|
12
7
|
end
|
13
8
|
|
14
9
|
def valid_get_treatments_parameters(split_names)
|
@@ -16,10 +11,7 @@ module SplitIoClient
|
|
16
11
|
end
|
17
12
|
|
18
13
|
def valid_track_parameters(key, traffic_type_name, event_type, value)
|
19
|
-
valid_track_key?(key) &&
|
20
|
-
valid_traffic_type_name?(traffic_type_name) &&
|
21
|
-
valid_event_type?(event_type) &&
|
22
|
-
valid_value?(value)
|
14
|
+
valid_track_key?(key) && valid_traffic_type_name?(traffic_type_name) && valid_event_type?(event_type) && valid_value?(value)
|
23
15
|
end
|
24
16
|
|
25
17
|
def valid_split_parameters(split_name)
|
@@ -52,7 +44,7 @@ module SplitIoClient
|
|
52
44
|
SplitIoClient.configuration.logger.warn("#{method}: #{key} is not of type String, converting to String")
|
53
45
|
end
|
54
46
|
|
55
|
-
def valid_split_name?(split_name, method
|
47
|
+
def valid_split_name?(split_name, method=:get_treatment)
|
56
48
|
if split_name.nil?
|
57
49
|
log_nil(:split_name, method)
|
58
50
|
return false
|
@@ -63,7 +55,7 @@ module SplitIoClient
|
|
63
55
|
return false
|
64
56
|
end
|
65
57
|
|
66
|
-
true
|
58
|
+
return true
|
67
59
|
end
|
68
60
|
|
69
61
|
def valid_key?(key)
|
@@ -72,7 +64,7 @@ module SplitIoClient
|
|
72
64
|
return false
|
73
65
|
end
|
74
66
|
|
75
|
-
true
|
67
|
+
return true
|
76
68
|
end
|
77
69
|
|
78
70
|
def valid_matching_key?(matching_key)
|
@@ -86,16 +78,16 @@ module SplitIoClient
|
|
86
78
|
return false
|
87
79
|
end
|
88
80
|
|
89
|
-
|
81
|
+
if matching_key.is_a? Numeric
|
82
|
+
log_convert_numeric(:matching_key, :get_treatment)
|
83
|
+
end
|
90
84
|
|
91
|
-
true
|
85
|
+
return true
|
92
86
|
end
|
93
87
|
|
94
|
-
def valid_bucketing_key?(
|
88
|
+
def valid_bucketing_key?(bucketing_key)
|
95
89
|
if bucketing_key.nil?
|
96
|
-
|
97
|
-
SplitIoClient.configuration.logger.warn('get_treatment: key object should have bucketing_key set')
|
98
|
-
end
|
90
|
+
SplitIoClient.configuration.logger.warn('get_treatment: key object should have bucketing_key set')
|
99
91
|
return true
|
100
92
|
end
|
101
93
|
|
@@ -104,9 +96,11 @@ module SplitIoClient
|
|
104
96
|
return false
|
105
97
|
end
|
106
98
|
|
107
|
-
|
99
|
+
if bucketing_key.is_a? Numeric
|
100
|
+
log_convert_numeric(:bucketing_key, :get_treatment)
|
101
|
+
end
|
108
102
|
|
109
|
-
true
|
103
|
+
return true
|
110
104
|
end
|
111
105
|
|
112
106
|
def valid_split_names?(split_names)
|
@@ -120,7 +114,7 @@ module SplitIoClient
|
|
120
114
|
return false
|
121
115
|
end
|
122
116
|
|
123
|
-
true
|
117
|
+
return true
|
124
118
|
end
|
125
119
|
|
126
120
|
def valid_track_key?(key)
|
@@ -134,9 +128,11 @@ module SplitIoClient
|
|
134
128
|
return false
|
135
129
|
end
|
136
130
|
|
137
|
-
|
131
|
+
if key.is_a? Numeric
|
132
|
+
log_convert_numeric(:key, :track)
|
133
|
+
end
|
138
134
|
|
139
|
-
true
|
135
|
+
return true
|
140
136
|
end
|
141
137
|
|
142
138
|
def valid_event_type?(event_type)
|
@@ -155,7 +151,7 @@ module SplitIoClient
|
|
155
151
|
return false
|
156
152
|
end
|
157
153
|
|
158
|
-
true
|
154
|
+
return true
|
159
155
|
end
|
160
156
|
|
161
157
|
def valid_traffic_type_name?(traffic_type_name)
|
@@ -174,7 +170,7 @@ module SplitIoClient
|
|
174
170
|
return false
|
175
171
|
end
|
176
172
|
|
177
|
-
true
|
173
|
+
return true
|
178
174
|
end
|
179
175
|
|
180
176
|
def valid_value?(value)
|
@@ -183,7 +179,7 @@ module SplitIoClient
|
|
183
179
|
return false
|
184
180
|
end
|
185
181
|
|
186
|
-
true
|
182
|
+
return true
|
187
183
|
end
|
188
184
|
end
|
189
185
|
end
|
data/splitclient-rb.gemspec
CHANGED
@@ -17,6 +17,8 @@ Gem::Specification.new do |spec|
|
|
17
17
|
|
18
18
|
spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(spec|features|ext)/}) }
|
19
19
|
|
20
|
+
spec.bindir = 'exe'
|
21
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
20
22
|
spec.require_paths = ['lib']
|
21
23
|
|
22
24
|
if defined?(JRUBY_VERSION)
|
@@ -51,7 +53,7 @@ Gem::Specification.new do |spec|
|
|
51
53
|
spec.add_runtime_dependency 'faraday', '>= 0.8'
|
52
54
|
spec.add_runtime_dependency 'json', '>= 1.8'
|
53
55
|
spec.add_runtime_dependency 'lru_redux'
|
54
|
-
spec.add_runtime_dependency 'net-http-persistent', '
|
56
|
+
spec.add_runtime_dependency 'net-http-persistent', '~> 3.0'
|
55
57
|
spec.add_runtime_dependency 'redis', '>= 3.2'
|
56
58
|
spec.add_runtime_dependency 'thread_safe', '>= 0.3'
|
57
59
|
end
|
data/splitio.yml.example
ADDED
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: 5.1.
|
4
|
+
version: 5.1.4.pre.rc1
|
5
5
|
platform: java
|
6
6
|
authors:
|
7
7
|
- Split Software
|
8
8
|
autorequire:
|
9
|
-
bindir:
|
9
|
+
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-
|
11
|
+
date: 2018-11-22 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
requirement: !ruby/object:Gem::Requirement
|
@@ -223,17 +223,17 @@ dependencies:
|
|
223
223
|
- !ruby/object:Gem::Dependency
|
224
224
|
requirement: !ruby/object:Gem::Requirement
|
225
225
|
requirements:
|
226
|
-
- - "
|
226
|
+
- - "~>"
|
227
227
|
- !ruby/object:Gem::Version
|
228
|
-
version: '
|
228
|
+
version: '3.0'
|
229
229
|
name: net-http-persistent
|
230
230
|
prerelease: false
|
231
231
|
type: :runtime
|
232
232
|
version_requirements: !ruby/object:Gem::Requirement
|
233
233
|
requirements:
|
234
|
-
- - "
|
234
|
+
- - "~>"
|
235
235
|
- !ruby/object:Gem::Version
|
236
|
-
version: '
|
236
|
+
version: '3.0'
|
237
237
|
- !ruby/object:Gem::Dependency
|
238
238
|
requirement: !ruby/object:Gem::Requirement
|
239
239
|
requirements:
|
@@ -265,7 +265,8 @@ dependencies:
|
|
265
265
|
description: Ruby client for using split SDK.
|
266
266
|
email:
|
267
267
|
- pato@split.io
|
268
|
-
executables:
|
268
|
+
executables:
|
269
|
+
- splitio
|
269
270
|
extensions: []
|
270
271
|
extra_rdoc_files: []
|
271
272
|
files:
|
@@ -278,6 +279,7 @@ files:
|
|
278
279
|
- NEWS
|
279
280
|
- README.md
|
280
281
|
- Rakefile
|
282
|
+
- exe/splitio
|
281
283
|
- ext/murmurhash/MurmurHash3.java
|
282
284
|
- lib/murmurhash/base.rb
|
283
285
|
- lib/murmurhash/murmurhash.jar
|
@@ -361,6 +363,7 @@ files:
|
|
361
363
|
- lib/splitclient-rb/validators.rb
|
362
364
|
- lib/splitclient-rb/version.rb
|
363
365
|
- splitclient-rb.gemspec
|
366
|
+
- splitio.yml.example
|
364
367
|
- tasks/benchmark_get_treatment.rake
|
365
368
|
- tasks/irb.rake
|
366
369
|
- tasks/rspec.rake
|