splitclient-rb 6.1.0 → 6.2.0.pre.rc1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (34) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +3 -0
  3. data/.rubocop.yml +1 -0
  4. data/Appraisals +10 -0
  5. data/Detailed-README.md +55 -5
  6. data/Rakefile +8 -1
  7. data/gemfiles/faraday_after_0.13.gemfile +7 -0
  8. data/gemfiles/faraday_before_0.13.gemfile +8 -0
  9. data/lib/splitclient-rb/cache/adapters/cache_adapter.rb +0 -1
  10. data/lib/splitclient-rb/cache/adapters/redis_adapter.rb +2 -3
  11. data/lib/splitclient-rb/cache/repositories/events/memory_repository.rb +4 -0
  12. data/lib/splitclient-rb/cache/repositories/events/redis_repository.rb +14 -2
  13. data/lib/splitclient-rb/cache/repositories/events_repository.rb +1 -1
  14. data/lib/splitclient-rb/cache/repositories/impressions/memory_repository.rb +4 -0
  15. data/lib/splitclient-rb/cache/repositories/impressions/redis_repository.rb +10 -2
  16. data/lib/splitclient-rb/cache/repositories/impressions_repository.rb +1 -1
  17. data/lib/splitclient-rb/cache/repositories/segments_repository.rb +1 -1
  18. data/lib/splitclient-rb/cache/repositories/splits_repository.rb +1 -1
  19. data/lib/splitclient-rb/cache/senders/events_sender.rb +12 -5
  20. data/lib/splitclient-rb/cache/senders/impressions_formatter.rb +3 -2
  21. data/lib/splitclient-rb/cache/senders/impressions_sender.rb +7 -8
  22. data/lib/splitclient-rb/cache/senders/metrics_sender.rb +10 -4
  23. data/lib/splitclient-rb/clients/split_client.rb +7 -5
  24. data/lib/splitclient-rb/engine/api/client.rb +21 -0
  25. data/lib/splitclient-rb/engine/api/faraday_adapter/patched_net_http_persistent.rb +46 -0
  26. data/lib/splitclient-rb/engine/parser/split_adapter.rb +1 -1
  27. data/lib/splitclient-rb/exceptions.rb +1 -1
  28. data/lib/splitclient-rb/split_config.rb +1 -1
  29. data/lib/splitclient-rb/split_factory.rb +16 -14
  30. data/lib/splitclient-rb/version.rb +1 -1
  31. data/lib/splitclient-rb.rb +1 -0
  32. data/splitclient-rb.gemspec +1 -0
  33. metadata +22 -5
  34. data/tasks/rspec.rake +0 -5
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 799cb7cc072735ec1d38ee26e6adb11abaf3d96a6d1981f97785735c417c5ddd
4
- data.tar.gz: 59b4b04bab3ad6a63f9a6e135b52cba1af49364b2cb753481d9bad2ae9be9a96
3
+ metadata.gz: c45535b20ee4c539f3876f2dcc8f402c2deb19b140a849c292225ecb051e7cdb
4
+ data.tar.gz: 24005ef65f4080d89e4b2ca30db2cc8f16f70c7e524fc92e9903fce2347e08d3
5
5
  SHA512:
6
- metadata.gz: 52fb852bf94f6a7ec54881742e1648a85f89d66dd2ef74a5dedb98d60d4c736cd85f99a1b61043371bdff73ad038ac1baae196c681f01049153f5f75b48f2247
7
- data.tar.gz: b49c0c82fc6beef2c6d1eb26847c35c37807dd2ed15e76a0daf20b951815b1820f8ce30ad23410415ad9088b8df1cdf86aadccebd83ec59f57f50f77dd5fac94
6
+ metadata.gz: 07be0c01951df6acfde4254aa57c312e2bf77ae18fe97e1db9aa3aa95c233aab1d4e229aaedab3c0dc75afed0ad4562d26d8f18c0570a78c95589c1cd9755791
7
+ data.tar.gz: 8d1cd43002b2fbee1f34349fdb3c905810af12685ce41f4474072e3a6944a0aa444aa359e123848ee3ef0efada7d6a2e6b286aa837b329d0f7c9994b354f3ed6
data/.gitignore CHANGED
@@ -49,3 +49,6 @@ dump.rdb
49
49
 
50
50
  # Ignore Mac OS generated files
51
51
  .DS_Store
52
+
53
+ # Ignore Appraisal gemfile.lock files
54
+ /gemfiles/*.gemfile.lock
data/.rubocop.yml CHANGED
@@ -19,6 +19,7 @@ Naming/FileName:
19
19
  AllCops:
20
20
  TargetRubyVersion: 2.3.6
21
21
  Exclude:
22
+ - gemfiles/* # excluded as appraisal generates them with errors
22
23
  - lib/*
23
24
  - lib/murmurhash/**/*
24
25
  - lib/splitclient-rb/*
data/Appraisals ADDED
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ appraise 'faraday-before-0.13' do
4
+ gem 'faraday', '>= 0.9', '< 0.13'
5
+ gem 'net-http-persistent', '~> 3.0'
6
+ end
7
+
8
+ appraise 'faraday-after-0.13' do
9
+ gem 'faraday', '> 0.13'
10
+ end
data/Detailed-README.md CHANGED
@@ -206,6 +206,57 @@ The split client will return `on`. Note that this will be true for any bucketing
206
206
  factory = SplitIoClient::SplitFactoryBuilder.build('localhost', path: '/where/to-look-for/<file_name>', reload_rate: 3)
207
207
  ```
208
208
 
209
+ ### SDK Input Validations
210
+
211
+ 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.
212
+
213
+ #### get_treatment (split_client)
214
+
215
+ - `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.
216
+
217
+ - `matching_key`, `bucketing_key`: the containing `Hash` must have both keys, and the same rules above apply for each.
218
+
219
+ - `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.
220
+
221
+ - `attributes`: must be of type `Hash`.
222
+
223
+ #### get_treatments (split_client)
224
+
225
+ - `key`, `matching_key`, `bucketing_key`: same rules as those for `get_treatment` apply.
226
+
227
+ - `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.
228
+
229
+ #### track (split_client)
230
+
231
+ - `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.
232
+
233
+ - `traffic_type_name`: must be a non-empty `String` or a `Symbol`. If `traffic_type_name` contains uppercase letters, it will be lowercased.
234
+
235
+ - `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).
236
+
237
+ - `value`: must be either a non-NaN `Numeric` value, or nil.
238
+
239
+ #### split (split_manager)
240
+
241
+ - `split_name`: must be a non-empty `String` or a `Symbol`.
242
+
243
+ #### Configuration Parameters
244
+
245
+ - `api_key`: must be a non-empty `String` or a `Symbol` of type `sdk` (`browser` type API keys will break this rule).
246
+
247
+ - `block_until_ready`: a warning log message will be issued if this value is not set.
248
+
249
+
250
+ #### Client Destroyed Rules
251
+ Calls to the SDK methods are still possible after `destroy` is called. All will log an error message stating _client has been destroyed_.
252
+
253
+ - `get_treatment` will return `control` for all calls (`get_treatments`, will return an Array of `control` values, correspondingly).
254
+
255
+ - Calls to `track` will return `false`.
256
+
257
+ - All calls to `split_manager` methods will return an empty Array, except `split`, which will return `nil`.
258
+
259
+
209
260
  ## Advanced Configuration
210
261
 
211
262
  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.:
@@ -280,6 +331,8 @@ The following values can be customized:
280
331
 
281
332
  **block_until_ready** : The SDK will block your app for the provided amount of seconds until it's ready. A `SplitIoClient::SDKBlockerTimeoutExpiredException` will be thrown If the provided time expires. When `0` is provided, the SDK runs in non-blocking mode.
282
333
 
334
+ _When using consumer mode, blocking has no effect._
335
+
283
336
  *default value* = `0`
284
337
 
285
338
  **labels_enabled** : Allows preventing labels from being sent to the Split servers, as they may contain sensitive information.
@@ -349,11 +402,8 @@ options = {
349
402
  mode: :consumer,
350
403
  redis_url: 'redis://127.0.0.1:6379/0'
351
404
  }
352
- begin
353
- split_client = SplitIoClient::SplitFactoryBuilder.build('YOUR_API_KEY', options).client
354
- rescue SplitIoClient::SDKBlockerTimeoutExpiredException
355
- # Code to treat raised exception
356
- end
405
+
406
+ split_client = SplitIoClient::SplitFactoryBuilder.build('YOUR_API_KEY', options).client
357
407
  ```
358
408
 
359
409
  ### Logging
data/Rakefile CHANGED
@@ -3,6 +3,7 @@
3
3
  require 'bundler/gem_tasks'
4
4
  require 'rspec/core/rake_task'
5
5
  require 'rubocop/rake_task'
6
+ require 'appraisal'
6
7
 
7
8
  Dir['tasks/**/*.rake'].each { |rake| load rake }
8
9
 
@@ -25,4 +26,10 @@ else
25
26
  end
26
27
  end
27
28
 
28
- task default: %i[spec rubocop]
29
+ if !ENV['APPRAISAL_INITIALIZED']
30
+ task :default do
31
+ sh 'appraisal install && rake appraisal && rake rubocop'
32
+ end
33
+ else
34
+ task default: %i[spec rubocop]
35
+ end
@@ -0,0 +1,7 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "https://rubygems.org"
4
+
5
+ gem "faraday", "> 0.13"
6
+
7
+ gemspec path: "../"
@@ -0,0 +1,8 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "https://rubygems.org"
4
+
5
+ gem "faraday", ">= 0.9", "< 0.13"
6
+ gem "net-http-persistent", "~> 3.0"
7
+
8
+ gemspec path: "../"
@@ -19,7 +19,6 @@ module SplitIoClient
19
19
 
20
20
  def clear(namespace_key)
21
21
  @cache.clear
22
- @adapter.clear(namespace_key)
23
22
  end
24
23
 
25
24
  def string(key)
@@ -125,6 +125,7 @@ module SplitIoClient
125
125
  @redis.rpush(key, val)
126
126
  end
127
127
 
128
+ # count = 0 will result in lrange(0,-1), fetching all items
128
129
  def get_from_queue(key, count)
129
130
  items = @redis.lrange(key, 0, count - 1)
130
131
  fetched_count = items.size
@@ -157,9 +158,7 @@ module SplitIoClient
157
158
  end
158
159
 
159
160
  def clear(prefix)
160
- keys = @redis.keys("#{prefix}*")
161
-
162
- keys.map { |key| @redis.del(key) }
161
+ # noop
163
162
  end
164
163
 
165
164
  def expire(key, seconds)
@@ -19,6 +19,10 @@ module SplitIoClient
19
19
  @adapter.clear
20
20
  end
21
21
 
22
+ def batch
23
+ @adapter.get_batch(EVENTS_SLICE)
24
+ end
25
+
22
26
  def clear
23
27
  @adapter.clear
24
28
  end
@@ -16,11 +16,23 @@ module SplitIoClient
16
16
  )
17
17
  end
18
18
 
19
- def clear
20
- @adapter.get_from_queue(namespace_key('.events'), EVENTS_SLICE).map do |e|
19
+ def get_events(number_of_events = 0)
20
+ @adapter.get_from_queue(namespace_key('.events'), number_of_events).map do |e|
21
21
  JSON.parse(e, symbolize_names: true)
22
22
  end
23
+ rescue StandardError => e
24
+ SplitIoClient.configuration.logger.error("Exception while clearing events cache: #{e}")
25
+ []
26
+ end
27
+
28
+ def batch
29
+ get_events(EVENTS_SLICE)
23
30
  end
31
+
32
+ def clear
33
+ get_events
34
+ end
35
+
24
36
  end
25
37
  end
26
38
  end
@@ -4,7 +4,7 @@ module SplitIoClient
4
4
  # Repository which forwards events interface to the selected adapter
5
5
  class EventsRepository < Repository
6
6
  extend Forwardable
7
- def_delegators :@adapter, :add, :clear
7
+ def_delegators :@adapter, :add, :clear, :batch
8
8
 
9
9
  def initialize(adapter)
10
10
  @adapter = case adapter.class.to_s
@@ -41,6 +41,10 @@ module SplitIoClient
41
41
  @adapter.get_batch(SplitIoClient.configuration.impressions_bulk_size)
42
42
  end
43
43
 
44
+ def clear
45
+ @adapter.clear
46
+ end
47
+
44
48
  private
45
49
 
46
50
  def random_sampler
@@ -35,8 +35,8 @@ module SplitIoClient
35
35
  @adapter.expire(key, EXPIRE_SECONDS) if impressions.size == impressions_list_size
36
36
  end
37
37
 
38
- def batch
39
- @adapter.get_from_queue(key, SplitIoClient.configuration.impressions_bulk_size).map do |e|
38
+ def get_impressions(number_of_impressions = 0)
39
+ @adapter.get_from_queue(key, number_of_impressions).map do |e|
40
40
  impression = JSON.parse(e, symbolize_names: true)
41
41
  impression[:i][:f] = impression[:i][:f].to_sym
42
42
  impression
@@ -46,6 +46,14 @@ module SplitIoClient
46
46
  []
47
47
  end
48
48
 
49
+ def batch
50
+ get_impressions(SplitIoClient.configuration.impressions_bulk_size)
51
+ end
52
+
53
+ def clear
54
+ get_impressions
55
+ end
56
+
49
57
  def key
50
58
  @key ||= namespace_key('.impressions')
51
59
  end
@@ -6,7 +6,7 @@ module SplitIoClient
6
6
  # Repository which forwards impressions interface to the selected adapter
7
7
  class ImpressionsRepository < Repository
8
8
  extend Forwardable
9
- def_delegators :@adapter, :add, :add_bulk, :batch, :empty?
9
+ def_delegators :@adapter, :add, :add_bulk, :batch, :clear, :empty?
10
10
 
11
11
  def initialize(adapter)
12
12
  @adapter = case adapter.class.to_s
@@ -13,7 +13,7 @@ module SplitIoClient
13
13
  else
14
14
  adapter
15
15
  end
16
- @adapter.set_bool(namespace_key('.ready'), false) unless SplitIoClient.configuration.mode == :consumer
16
+ @adapter.set_bool(namespace_key('.ready'), false) unless SplitIoClient.configuration.mode.equal?(:consumer)
17
17
  end
18
18
 
19
19
  # Receives segment data, adds and removes segements from the store
@@ -13,7 +13,7 @@ module SplitIoClient
13
13
  else
14
14
  adapter
15
15
  end
16
- unless SplitIoClient.configuration.mode == :consumer
16
+ unless SplitIoClient.configuration.mode.equal?(:consumer)
17
17
  @adapter.set_string(namespace_key('.splits.till'), '-1')
18
18
  @adapter.initialize_map(namespace_key('.segments.registered'))
19
19
  end
@@ -27,18 +27,25 @@ module SplitIoClient
27
27
 
28
28
  def events_thread
29
29
  SplitIoClient.configuration.threads[:events_sender] = Thread.new do
30
- SplitIoClient.configuration.logger.info('Starting events service')
30
+ begin
31
+ SplitIoClient.configuration.logger.info('Starting events service')
32
+
33
+ loop do
34
+ post_events(false)
31
35
 
32
- loop do
36
+ sleep(SplitIoClient::Utilities.randomize_interval(SplitIoClient.configuration.events_push_rate))
37
+ end
38
+ rescue SplitIoClient::SDKShutdownException
33
39
  post_events
34
40
 
35
- sleep(SplitIoClient::Utilities.randomize_interval(SplitIoClient.configuration.events_push_rate))
41
+ SplitIoClient.configuration.logger.info('Posting events due to shutdown')
36
42
  end
37
43
  end
38
44
  end
39
45
 
40
- def post_events
41
- events_api.post(@events_repository.clear)
46
+ def post_events(fetch_all_events = true)
47
+ events = fetch_all_events ? @events_repository.clear : @events_repository.batch
48
+ events_api.post(events)
42
49
  rescue StandardError => error
43
50
  SplitIoClient.configuration.log_found_exception(__method__.to_s, error)
44
51
  end
@@ -8,8 +8,9 @@ module SplitIoClient
8
8
  @impressions_repository = impressions_repository
9
9
  end
10
10
 
11
- def call(raw_impressions)
12
- impressions = raw_impressions || @impressions_repository.batch
11
+ def call(fetch_all_impressions, raw_impressions = nil)
12
+ impressions = raw_impressions || (fetch_all_impressions ? @impressions_repository.clear : @impressions_repository.batch)
13
+
13
14
  filtered_impressions = filter_impressions(impressions)
14
15
 
15
16
  return [] if impressions.empty? || filtered_impressions.empty?
@@ -36,28 +36,27 @@ module SplitIoClient
36
36
  SplitIoClient.configuration.logger.info('Starting impressions service')
37
37
 
38
38
  loop do
39
- post_impressions
39
+ post_impressions(false)
40
40
 
41
41
  sleep(SplitIoClient::Utilities.randomize_interval(SplitIoClient.configuration.impressions_refresh_rate))
42
42
  end
43
- rescue SplitIoClient::ImpressionShutdownException
43
+ rescue SplitIoClient::SDKShutdownException
44
44
  post_impressions
45
45
 
46
- @impressions_repository.clear
46
+ SplitIoClient.configuration.logger.info('Posting impressions due to shutdown')
47
47
  end
48
48
  end
49
49
  end
50
50
 
51
- def post_impressions
51
+ def post_impressions(fetch_all_impressions = true)
52
+ formatted_impressions = ImpressionsFormatter.new(@impressions_repository)
53
+ .call(fetch_all_impressions)
54
+
52
55
  impressions_api.post(formatted_impressions)
53
56
  rescue StandardError => error
54
57
  SplitIoClient.configuration.log_found_exception(__method__.to_s, error)
55
58
  end
56
59
 
57
- def formatted_impressions(raw_impressions = nil)
58
- ImpressionsFormatter.new(@impressions_repository).call(raw_impressions)
59
- end
60
-
61
60
  def impressions_api
62
61
  @impressions_api ||= SplitIoClient::Api::Impressions.new(@api_key)
63
62
  end
@@ -25,12 +25,18 @@ module SplitIoClient
25
25
 
26
26
  def metrics_thread
27
27
  SplitIoClient.configuration.threads[:metrics_sender] = Thread.new do
28
- SplitIoClient.configuration.logger.info('Starting metrics service')
29
-
30
- loop do
28
+ begin
29
+ SplitIoClient.configuration.logger.info('Starting metrics service')
30
+
31
+ loop do
32
+ post_metrics
33
+
34
+ sleep(SplitIoClient::Utilities.randomize_interval(SplitIoClient.configuration.metrics_refresh_rate))
35
+ end
36
+ rescue SplitIoClient::SDKShutdownException
31
37
  post_metrics
32
38
 
33
- sleep(SplitIoClient::Utilities.randomize_interval(SplitIoClient.configuration.metrics_refresh_rate))
39
+ SplitIoClient.configuration.logger.info('Posting metrics due to shutdown')
34
40
  end
35
41
  end
36
42
  end
@@ -125,14 +125,16 @@ module SplitIoClient
125
125
 
126
126
  def destroy
127
127
  SplitIoClient.configuration.logger.info('Split client shutdown started...') if SplitIoClient.configuration.debug_enabled
128
- SplitIoClient.configuration.threads[:impressions_sender].raise(SplitIoClient::ImpressionShutdownException)
129
- SplitIoClient.configuration.threads.reject { |k, _| k == :impressions_sender }.each do |name, thread|
130
- Thread.kill(thread)
128
+
129
+ SplitIoClient.configuration.threads.select { |name, thread| name.to_s.end_with? 'sender' }.values.each do |thread|
130
+ thread.raise(SplitIoClient::SDKShutdownException)
131
+ thread.join
131
132
  end
132
- @metrics_repository.clear
133
+
134
+ SplitIoClient.configuration.threads.values.each { |thread| Thread.kill(thread) }
135
+
133
136
  @splits_repository.clear
134
137
  @segments_repository.clear
135
- @events_repository.clear
136
138
 
137
139
  SplitIoClient.configuration.logger.info('Split client shutdown complete') if SplitIoClient.configuration.debug_enabled
138
140
  SplitIoClient.configuration.valid_mode = false
@@ -43,12 +43,33 @@ module SplitIoClient
43
43
  private
44
44
 
45
45
  def api_client
46
+ if needs_patched_net_http_persistent_adapter?
47
+ require 'splitclient-rb/engine/api/faraday_adapter/patched_net_http_persistent'
48
+
49
+ Faraday::Adapter.register_middleware(
50
+ net_http_persistent: SplitIoClient::FaradayAdapter::PatchedNetHttpPersistent
51
+ )
52
+ end
53
+
46
54
  @api_client ||= Faraday.new do |builder|
47
55
  builder.use SplitIoClient::FaradayMiddleware::Gzip
48
56
  builder.adapter :net_http_persistent
49
57
  end
50
58
  end
51
59
 
60
+ def needs_patched_net_http_persistent_adapter?
61
+ new_net_http_persistent? && incompatible_faraday_version?
62
+ end
63
+
64
+ def incompatible_faraday_version?
65
+ version = Faraday::VERSION.split('.')[0..1]
66
+ version[0].to_i == 0 && version[1].to_i < 13
67
+ end
68
+
69
+ def new_net_http_persistent?
70
+ Net::HTTP::Persistent::VERSION.split('.').first.to_i >= 3
71
+ end
72
+
52
73
  def common_headers(api_key)
53
74
  {
54
75
  'Authorization' => "Bearer #{api_key}",
@@ -0,0 +1,46 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SplitIoClient
4
+ module FaradayAdapter
5
+ class PatchedNetHttpPersistent < Faraday::Adapter::NetHttpPersistent
6
+ ##
7
+ # Borrowed directly from the latest `NetHttpPersistent` adapter implementation.
8
+ #
9
+ # https://github.com/lostisland/faraday/blob/master/lib/faraday/adapter/net_http_persistent.rb
10
+ #
11
+ def net_http_connection(env)
12
+ @cached_connection ||=
13
+ if Net::HTTP::Persistent.instance_method(:initialize).parameters.first == [:key, :name]
14
+ Net::HTTP::Persistent.new(name: 'Faraday')
15
+ else
16
+ Net::HTTP::Persistent.new('Faraday')
17
+ end
18
+
19
+ proxy_uri = proxy_uri(env)
20
+ @cached_connection.proxy = proxy_uri if @cached_connection.proxy_uri != proxy_uri
21
+ @cached_connection
22
+ end
23
+
24
+ def proxy_uri(env)
25
+ proxy_uri = nil
26
+ if (proxy = env[:request][:proxy])
27
+ proxy_uri = ::URI::HTTP === proxy[:uri] ? proxy[:uri].dup : ::URI.parse(proxy[:uri].to_s)
28
+ proxy_uri.user = proxy_uri.password = nil
29
+ # awful patch for net-http-persistent 2.8 not unescaping user/password
30
+ (
31
+ class << proxy_uri;
32
+ self;
33
+ end).class_eval do
34
+ define_method(:user) { proxy[:user] }
35
+ define_method(:password) { proxy[:password] }
36
+ end if proxy[:user]
37
+ end
38
+ proxy_uri
39
+ end
40
+
41
+ def with_net_http_connection(env)
42
+ yield net_http_connection(env)
43
+ end
44
+ end
45
+ end
46
+ end
@@ -20,7 +20,7 @@ module SplitIoClient
20
20
  # @param splits_repository [SplitsRepository] SplitsRepository instance to store splits in
21
21
  # @param segments_repository [SegmentsRepository] SegmentsRepository instance to store segments in
22
22
  # @param impressions_repository [ImpressionsRepository] ImpressionsRepository instance to store impressions in
23
- # @param metrics_repository [MetricsRepository] SplitsRepository instance to store metrics in
23
+ # @param metrics_repository [MetricsRepository] MetricsRepository instance to store metrics in
24
24
  # @param sdk_blocker [SDKBlocker] SDKBlocker instance which blocks splits_repository/segments_repository
25
25
  #
26
26
  # @return [SplitIoClient] split.io client instance
@@ -1,7 +1,7 @@
1
1
  module SplitIoClient
2
2
  class SplitIoError < StandardError; end
3
3
 
4
- class ImpressionShutdownException < SplitIoError; end
4
+ class SDKShutdownException < SplitIoError; end
5
5
 
6
6
  class SDKBlockerTimeoutExpiredException < SplitIoError; end
7
7
  end
@@ -70,7 +70,7 @@ module SplitIoClient
70
70
  @transport_debug_enabled = opts[:transport_debug_enabled] || SplitConfig.default_debug
71
71
  @block_until_ready = opts[:ready] || opts[:block_until_ready] || 0
72
72
 
73
- @logger.warn 'no ready parameter has been set - incorrect control treatments could be logged' if block_until_ready == 0
73
+ @logger.warn 'no ready parameter has been set - incorrect control treatments could be logged' if block_until_ready == 0 && !mode.equal?(:consumer)
74
74
 
75
75
  @machine_name = opts[:machine_name] || SplitConfig.machine_hostname
76
76
  @machine_ip = opts[:machine_ip] || SplitConfig.machine_ip
@@ -7,6 +7,17 @@ module SplitIoClient
7
7
  attr_reader :adapter, :client, :manager
8
8
 
9
9
  def initialize(api_key, config_hash = {})
10
+ at_exit do
11
+ unless ENV['SPLITCLIENT_ENV'] == 'test'
12
+ if (Process.pid == ROOT_PROCESS_ID)
13
+ SplitIoClient.configuration.logger.info('Split SDK shutdown started...')
14
+ @client.destroy if @client
15
+ stop!
16
+ SplitIoClient.configuration.logger.info('Split SDK shutdown complete')
17
+ end
18
+ end
19
+ end
20
+
10
21
  @api_key = api_key
11
22
  SplitIoClient.configure(config_hash)
12
23
 
@@ -20,7 +31,10 @@ module SplitIoClient
20
31
  @metrics_repository = MetricsRepository.new(SplitIoClient.configuration.metrics_adapter)
21
32
  @events_repository = EventsRepository.new(SplitIoClient.configuration.events_adapter)
22
33
 
23
- @sdk_blocker = SDKBlocker.new(@splits_repository, @segments_repository)
34
+ if SplitIoClient.configuration.mode == :standalone && SplitIoClient.configuration.block_until_ready > 0
35
+ @sdk_blocker = SDKBlocker.new(@splits_repository, @segments_repository)
36
+ end
37
+
24
38
  @adapter = start!
25
39
 
26
40
  @client = SplitClient.new(@api_key, @adapter, @splits_repository, @segments_repository, @impressions_repository, @metrics_repository, @events_repository)
@@ -28,19 +42,7 @@ module SplitIoClient
28
42
 
29
43
  validate_api_key
30
44
 
31
- @sdk_blocker.block if SplitIoClient.configuration.block_until_ready > 0
32
-
33
-
34
- at_exit do
35
- unless ENV['SPLITCLIENT_ENV'] == 'test'
36
- if (Process.pid == ROOT_PROCESS_ID)
37
- SplitIoClient.configuration.logger.info('Split SDK shutdown started...')
38
- @client.destroy
39
- stop!
40
- SplitIoClient.configuration.logger.info('Split SDK shutdown complete')
41
- end
42
- end
43
- end
45
+ @sdk_blocker.block if @sdk_blocker
44
46
  end
45
47
 
46
48
  def start!
@@ -1,3 +1,3 @@
1
1
  module SplitIoClient
2
- VERSION = '6.1.0'
2
+ VERSION = '6.2.0.pre.rc1'
3
3
  end
@@ -41,6 +41,7 @@ require 'splitclient-rb/split_config'
41
41
  require 'splitclient-rb/split_logger'
42
42
 
43
43
  require 'splitclient-rb/engine/api/faraday_middleware/gzip'
44
+ require 'splitclient-rb/engine/api/faraday_adapter/patched_net_http_persistent'
44
45
  require 'splitclient-rb/engine/api/client'
45
46
  require 'splitclient-rb/engine/api/impressions'
46
47
  require 'splitclient-rb/engine/api/metrics'
@@ -36,6 +36,7 @@ Gem::Specification.new do |spec|
36
36
  end
37
37
 
38
38
  spec.add_development_dependency 'allocation_stats'
39
+ spec.add_development_dependency 'appraisal'
39
40
  spec.add_development_dependency 'bundler', '~> 1.11'
40
41
  spec.add_development_dependency 'pry'
41
42
  spec.add_development_dependency 'pry-nav'
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: 6.1.0
4
+ version: 6.2.0.pre.rc1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Split Software
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-02-08 00:00:00.000000000 Z
11
+ date: 2019-03-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: allocation_stats
@@ -24,6 +24,20 @@ dependencies:
24
24
  - - ">="
25
25
  - !ruby/object:Gem::Version
26
26
  version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: appraisal
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
27
41
  - !ruby/object:Gem::Dependency
28
42
  name: bundler
29
43
  requirement: !ruby/object:Gem::Requirement
@@ -273,6 +287,7 @@ files:
273
287
  - ".gitignore"
274
288
  - ".rubocop.yml"
275
289
  - ".simplecov"
290
+ - Appraisals
276
291
  - CHANGES.txt
277
292
  - Detailed-README.md
278
293
  - Gemfile
@@ -284,6 +299,8 @@ files:
284
299
  - ext/murmurhash/extconf.rb
285
300
  - ext/murmurhash/murmurhash.c
286
301
  - ext/murmurhash/murmurhash.h
302
+ - gemfiles/faraday_after_0.13.gemfile
303
+ - gemfiles/faraday_before_0.13.gemfile
287
304
  - lib/murmurhash/base.rb
288
305
  - lib/murmurhash/murmurhash.jar
289
306
  - lib/murmurhash/murmurhash_mri.rb
@@ -317,6 +334,7 @@ files:
317
334
  - lib/splitclient-rb/clients/split_client.rb
318
335
  - lib/splitclient-rb/engine/api/client.rb
319
336
  - lib/splitclient-rb/engine/api/events.rb
337
+ - lib/splitclient-rb/engine/api/faraday_adapter/patched_net_http_persistent.rb
320
338
  - lib/splitclient-rb/engine/api/faraday_middleware/gzip.rb
321
339
  - lib/splitclient-rb/engine/api/impressions.rb
322
340
  - lib/splitclient-rb/engine/api/metrics.rb
@@ -369,7 +387,6 @@ files:
369
387
  - splitclient-rb.gemspec
370
388
  - tasks/benchmark_get_treatment.rake
371
389
  - tasks/irb.rake
372
- - tasks/rspec.rake
373
390
  homepage: https://github.com/splitio/ruby-client
374
391
  licenses:
375
392
  - Apache 2.0
@@ -385,9 +402,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
385
402
  version: '0'
386
403
  required_rubygems_version: !ruby/object:Gem::Requirement
387
404
  requirements:
388
- - - ">="
405
+ - - ">"
389
406
  - !ruby/object:Gem::Version
390
- version: '0'
407
+ version: 1.3.1
391
408
  requirements: []
392
409
  rubyforge_project:
393
410
  rubygems_version: 2.7.6
data/tasks/rspec.rake DELETED
@@ -1,5 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'rspec/core/rake_task'
4
-
5
- RSpec::Core::RakeTask.new(:spec)