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

Sign up to get free protection for your applications and to get access to all the features.
data/Gemfile CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  source 'https://rubygems.org'
2
4
 
3
5
  # Specify your gem's dependencies in splitclient-rb.gemspec
data/NEWS CHANGED
@@ -1,3 +1,13 @@
1
+ 5.1.0
2
+
3
+ Prevent unhandled exceptions from raising when API get calls fail on Segments and Treatments.
4
+
5
+ 5.0.3
6
+
7
+ Creates a new configuration parameter (impressions_bulk_size) to manage the max number of impressions sent to the Split backend on each post.
8
+ Changes impressions_queue_size so that it manages only the queue size in the memory adapter.
9
+ A backwards compatibility fail safe is included for users of previous SDK versions.
10
+
1
11
  5.0.2
2
12
 
3
13
  Turn Impression Listener into an optional SDK feature.
@@ -5,13 +15,13 @@ Prevents the impression thread from being started if a listener is not in place
5
15
 
6
16
  5.0.1
7
17
 
8
- Adding stop! method to the factory.
18
+ Adding stop! method to the factory.
9
19
  With this method the user will be able to stop the threads that queries the Split Service. This will be used in the before_fork configuration in Puma and Unicorn to stop the threads in the master process.
10
20
 
11
21
  5.0.0
12
22
 
13
23
  This is a breaking change in how users buckets are allocated.
14
- Ruby SDK was wrongly picking up the right buckets and defauled to
24
+ Ruby SDK was wrongly picking up the right buckets and defauled to
15
25
  use a "legacy hashing" instead of our moder murmur3 algo which is
16
26
  what other SDKs use. Please reach out to support@split.io for help
17
27
  on how to upgrade to this release.
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 :spec => :compile
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 :default => :spec
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('../../lib', __FILE__)
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 = "Usage: splitio [options]"
16
+ opts.banner = 'Usage: splitio [options]'
16
17
 
17
- opts.on("-cPATH", "--config=PATH", "Set the path to splitio.yml config file") do |c|
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("--base-uri=BASE_URI", "Set the base uri for Split SDK") do |c|
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("--events-uri=EVENTS_URI", "Set the events uri for Split SDK") do |c|
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("--api-key=API_KEY", "Set the API Key for Split SDK") do |c|
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("--read-timeout=READ_TIMEOUT", "Read timeout in seconds") do |c|
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("--connection-timeout=CONNECTION_TIMEOUT", "Connection timeout in seconds") do |c|
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("--features-refresh-rate=FEATURES_REFRESH_RATE", "Features refresh rate in seconds") do |c|
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("--segments-refresh-rate=SEGMENTS_REFRESH_RATE", "Segments refresh rate in seconds") do |c|
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("--metrics-refresh-rate=METRICS_REFRESH_RATE", "Metrics refresh rate in seconds") do |c|
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("--impressions-refresh-rate=IMPRESSIONS_REFRESH_RATE", "Impressions refresh rate in seconds") do |c|
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("--ready=SECONDS", "Seconds to block the app until SDK is ready or false to run in non-blocking mode") do |c|
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("--redis-url=REDIS_URL", "Set base uri for Split SDK") do |c|
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("--transport-debug", "Enable transport debug") do
66
+ opts.on('--transport-debug', 'Enable transport debug') do
66
67
  options[:transport_debug_enabled] = true
67
68
  end
68
69
 
69
- opts.on("-d", "--debug", "Enable debug mode") do
70
+ opts.on('-d', '--debug', 'Enable debug mode') do
70
71
  options[:debug_enabled] = true
71
72
  end
72
73
 
73
- opts.on_tail("-h", "--help", "Prints this help") do
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
- .merge!(events_uri: ENV['EVENTS_URI'] || config[:events_uri])
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)
@@ -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'
@@ -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
- while true
20
- fetch_segments(name, prefix, since).each { |segment| @segments_repository.add_to_segment(segment) }
21
- @config.logger.debug("Segment #{name} fetched before: #{since}, till: #{@segments_repository.get_change_number(name)}") if @config.debug_enabled
23
+ loop do
24
+ segment = fetch_segment_changes(name, since)
25
+ @segments_repository.add_to_segment(segment)
22
26
 
23
- break if (since.to_i >= @segments_repository.get_change_number(name).to_i)
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(prefix + '.time', latency)
36
+ @metrics.time(METRICS_PREFIX + '.time', latency)
30
37
  end
31
38
 
32
39
  private
33
40
 
34
- def fetch_segments(name, prefix, since)
35
- segments = []
36
- segment = get_api("#{@config.base_uri}/segmentChanges/#{name}", @config, @api_key, since: since)
37
-
38
- if segment == false
39
- @config.logger.error("Failed to make a http request")
40
- elsif segment.status / 100 == 2
41
- segment_content = JSON.parse(segment.body, symbolize_names: true)
42
- @segments_repository.set_change_number(name, segment_content[:till])
43
- @metrics.count(prefix + '.status.' + segment.status.to_s, 1)
44
-
45
- if @config.debug_enabled
46
- @config.logger.debug("\'#{segment_content[:name]}\' segment retrieved.")
47
- @config.logger.debug("\'#{segment_content[:name]}\' #{segment_content[:added].size} added keys") if segment_content[:added].size > 0
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
- @config.logger.debug("#{segment_content}") if @config.transport_debug_enabled
56
+ SplitLogger.log_if_transport(segment.to_s)
51
57
 
52
- segments << segment_content
58
+ segment
53
59
  else
54
- @config.logger.error("Unexpected result from API Call for Segment #{name} status #{segment.status.to_s} since #{since.to_s}")
55
- @metrics.count(prefix + '.status.' + segment.status.to_s, 1)
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
- if splits == false
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
- @metrics.count(prefix + '.status.' + splits.status.to_s, 1)
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
- @config.logger.error('Unexpected result from Splits API call')
28
- end
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
- latency = (Time.now - start) * 1000.0
31
- @metrics.time(prefix + '.time', latency)
29
+ latency = (Time.now - start) * 1000.0
30
+ @metrics.time(METRICS_PREFIX + '.time', latency)
32
31
 
33
- result
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
@@ -1,3 +1,3 @@
1
1
  module SplitIoClient
2
- VERSION = '5.0.3.pre.rc1'
2
+ VERSION = '5.1.0'
3
3
  end
@@ -1,53 +1,57 @@
1
- # coding: utf-8
2
- lib = File.expand_path('../lib', __FILE__)
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 = "splitclient-rb"
8
+ spec.name = 'splitclient-rb'
8
9
  spec.version = SplitIoClient::VERSION
9
- spec.authors = ["Split Software"]
10
- spec.email = ["pato@split.io"]
10
+ spec.authors = ['Split Software']
11
+ spec.email = ['pato@split.io']
11
12
 
12
- spec.summary = %q{Ruby client for split SDK.}
13
- spec.description = %q{Ruby client for using split SDK.}
14
- spec.homepage = "https://github.com/splitio/ruby-client"
15
- spec.license = "Apache 2.0"
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 = "exe"
20
+ spec.bindir = 'exe'
20
21
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
21
- spec.require_paths = ["lib"]
22
+ spec.require_paths = ['lib']
22
23
 
23
24
  if defined?(JRUBY_VERSION)
24
25
  spec.platform = 'java'
25
- spec.files.concat(%w(
26
- ext/murmurhash/MurmurHash3.java
27
- lib/murmurhash/murmurhash.jar)
26
+ spec.files.concat(
27
+ %w[ext/murmurhash/MurmurHash3.java
28
+ lib/murmurhash/murmurhash.jar]
28
29
  )
29
30
  else
30
- spec.files.concat(%w(
31
- ext/murmurhash/3_x86_32.c
32
- ext/murmurhash/extconf.rb
33
- ext/murmurhash/murmurhash.c
34
- ext/murmurhash/murmurhash.h)
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 = ["ext/murmurhash/extconf.rb"]
37
+ spec.extensions = ['ext/murmurhash/extconf.rb']
37
38
  end
38
39
 
39
- spec.add_development_dependency "bundler", "~> 1.11"
40
- spec.add_development_dependency "rake", "~> 10.0"
41
- spec.add_development_dependency "rake-compiler"
42
- spec.add_development_dependency "rspec"
43
- spec.add_development_dependency "webmock"
44
- spec.add_development_dependency "simplecov"
45
- spec.add_development_dependency "allocation_stats"
46
-
47
- spec.add_runtime_dependency "json", ">= 1.8"
48
- spec.add_runtime_dependency "thread_safe", ">= 0.3"
49
- spec.add_runtime_dependency "concurrent-ruby", "~> 1.0"
50
- spec.add_runtime_dependency "faraday", ">= 0.8"
51
- spec.add_runtime_dependency "net-http-persistent", "~> 2.9"
52
- spec.add_runtime_dependency "redis", ">= 3.2"
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