splitclient-rb 7.3.1.pre.rc1-java → 7.3.2-java

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: e4c38ff221566b6a030d3701c703ab5f73ca94fb
4
- data.tar.gz: '081b5b1132ed42843658e3a33bcce62d1465dac3'
3
+ metadata.gz: 7237dc328456c0eb3c6db4d51baba65df84f5d41
4
+ data.tar.gz: f4e1859a0014c14fa7fdbf81f0cc472e2cc6a99e
5
5
  SHA512:
6
- metadata.gz: c5b7a1e7d7332bfd1180974a57890e3e2f4919a14dba9ed7ee137906a803ae38a733cea56f837a35ed20801d085184cd9bf65656cdb16fc774f79a117c980ea3
7
- data.tar.gz: 7e849dda094c87cd2495749be25aa877bf6b3e91c420acfee38bb38cf9604c7fffe58bd7a80669837f918d50762fb2d2ee7800889515a6abb2f1543de64956d7
6
+ metadata.gz: 00f9f235011c0d248e92e92b5267e17d78da3fd48dc70f21a53ad5a5936190565307b6871e96988c99c5820f952ea6538074ac4f8d09e3f045562ca415ed1f1b
7
+ data.tar.gz: 06bb9639c826e606b1d24afdb994b60dbeb3ccaf4e28c2275f6b717b435e8c29421d4a7ce802a672d64765bdcb5072a9acd3346b0780afdd73324fc4eea6a7e1
@@ -0,0 +1,78 @@
1
+ on:
2
+ push:
3
+ branches:
4
+ - master
5
+ pull_request:
6
+ branches:
7
+ - master
8
+
9
+ jobs:
10
+ test:
11
+ runs-on: ubuntu-latest
12
+ services:
13
+ redis:
14
+ image: redis
15
+ ports:
16
+ - 6379:6379
17
+ steps:
18
+ - name: Checkout code
19
+ uses: actions/checkout@v2
20
+ with:
21
+ fetch-depth: 0
22
+
23
+ - name: Set up Ruby
24
+ uses: ruby/setup-ruby@477b21f02be01bcb8030d50f37cfec92bfa615b6
25
+ with:
26
+ ruby-version: 2.5
27
+
28
+ - name: Install dependencies
29
+ run: bundle install
30
+
31
+ - name: Run tests
32
+ run: bundle exec rake
33
+
34
+ - name: Fix code coverage paths
35
+ working-directory: ./coverage
36
+ run: |
37
+ sed -i 's@'$GITHUB_WORKSPACE'@/github/workspace/@g' .resultset.json
38
+ ruby -rjson -e 'sqube = JSON.load(File.read(".resultset.json"))["RSpec"]["coverage"].transform_values {|lines| lines["lines"]}; total = { "RSpec" => { "coverage" => sqube, "timestamp" => Time.now.to_i }}; puts JSON.dump(total)' > .resultset.sonarqube.json
39
+
40
+
41
+ - name: SonarQube Scan (Push)
42
+ if: github.event_name == 'push'
43
+ uses: SonarSource/sonarcloud-github-action@v1.5
44
+ env:
45
+ SONAR_TOKEN: ${{ secrets.SONARQUBE_TOKEN }}
46
+ with:
47
+ projectBaseDir: .
48
+ args: >
49
+ -Dsonar.host.url=${{ secrets.SONARQUBE_HOST }}
50
+ -Dsonar.projectName=${{ github.event.repository.name }}
51
+ -Dsonar.projectKey=${{ github.event.repository.name }}
52
+ -Dsonar.ruby.coverage.reportPaths=coverage/.resultset.sonarqube.json
53
+ -Dsonar.c.file.suffixes=-
54
+ -Dsonar.cpp.file.suffixes=-
55
+ -Dsonar.objc.file.suffixes=-
56
+ -Dsonar.links.ci="https://github.com/splitio/${{ github.event.repository.name }}/actions"
57
+ -Dsonar.links.scm="https://github.com/splitio/${{ github.event.repository.name }}"
58
+
59
+ - name: SonarQube Scan (Pull Request)
60
+ if: github.event_name == 'pull_request'
61
+ uses: SonarSource/sonarcloud-github-action@v1.5
62
+ env:
63
+ SONAR_TOKEN: ${{ secrets.SONARQUBE_TOKEN }}
64
+ with:
65
+ projectBaseDir: .
66
+ args: >
67
+ -Dsonar.host.url=${{ secrets.SONARQUBE_HOST }}
68
+ -Dsonar.projectName=${{ github.event.repository.name }}
69
+ -Dsonar.projectKey=${{ github.event.repository.name }}
70
+ -Dsonar.ruby.coverage.reportPaths=coverage/.resultset.sonarqube.json
71
+ -Dsonar.c.file.suffixes=-
72
+ -Dsonar.cpp.file.suffixes=-
73
+ -Dsonar.objc.file.suffixes=-
74
+ -Dsonar.links.ci="https://github.com/splitio/${{ github.event.repository.name }}/actions"
75
+ -Dsonar.links.scm="https://github.com/splitio/${{ github.event.repository.name }}"
76
+ -Dsonar.pullrequest.key=${{ github.event.pull_request.number }}
77
+ -Dsonar.pullrequest.branch=${{ github.event.pull_request.head.ref }}
78
+ -Dsonar.pullrequest.base=${{ github.event.pull_request.base.ref }}
data/.rubocop.yml CHANGED
@@ -64,3 +64,4 @@ AllCops:
64
64
  - lib/splitclient-rb/engine/parser/**/*
65
65
  - spec/telemetry/synchronizer_spec.rb
66
66
  - lib/splitclient-rb/engine/synchronizer.rb
67
+ - tmp/**/*
data/CHANGES.txt CHANGED
@@ -1,5 +1,12 @@
1
1
  CHANGES
2
2
 
3
+ 7.3.2 (Dec 10, 2021)
4
+ - Updated the readiness flow to be more consistent with the other sdks and improve the readiness time.
5
+ - Updated the name of telemety key latencies in Redis.
6
+
7
+ 7.3.1 (Jul 26, 2021)
8
+ - Updated the synchronization flow to be more reliable in the event of an edge case generating delay in cache purge propagation, keeping the SDK cache properly synced.
9
+
3
10
  7.3.0 (Jul 12, 2021)
4
11
  - Updated SDK telemetry storage, metrics and updater to be more effective and send less often.
5
12
  - Fixed high cpu usage when api key is wrong.
@@ -4,11 +4,10 @@ module SplitIoClient
4
4
  class SegmentFetcher
5
5
  attr_reader :segments_repository
6
6
 
7
- def initialize(segments_repository, api_key, config, sdk_blocker, telemetry_runtime_producer)
7
+ def initialize(segments_repository, api_key, config, telemetry_runtime_producer)
8
8
  @segments_repository = segments_repository
9
9
  @api_key = api_key
10
10
  @config = config
11
- @sdk_blocker = sdk_blocker
12
11
  @semaphore = Mutex.new
13
12
  @telemetry_runtime_producer = telemetry_runtime_producer
14
13
  end
@@ -52,11 +51,11 @@ module SplitIoClient
52
51
  @semaphore.synchronize do
53
52
  segments_api.fetch_segments_by_names(@segments_repository.used_segment_names)
54
53
 
55
- @sdk_blocker.segments_ready!
56
- @sdk_blocker.sdk_internal_ready
54
+ true
57
55
  end
58
56
  rescue StandardError => error
59
57
  @config.log_found_exception(__method__.to_s, error)
58
+ false
60
59
  end
61
60
 
62
61
  def stop_segments_thread
@@ -70,11 +69,6 @@ module SplitIoClient
70
69
  @config.logger.info('Starting segments fetcher service') if @config.debug_enabled
71
70
 
72
71
  loop do
73
- unless @sdk_blocker.splits_repository.ready?
74
- sleep 0.2
75
- next
76
- end
77
-
78
72
  fetch_segments
79
73
  @config.logger.debug("Segment names: #{@segments_repository.used_segment_names.to_a}") if @config.debug_enabled
80
74
 
@@ -4,11 +4,10 @@ module SplitIoClient
4
4
  class SplitFetcher
5
5
  attr_reader :splits_repository
6
6
 
7
- def initialize(splits_repository, api_key, config, sdk_blocker, telemetry_runtime_producer)
7
+ def initialize(splits_repository, api_key, config, telemetry_runtime_producer)
8
8
  @splits_repository = splits_repository
9
9
  @api_key = api_key
10
10
  @config = config
11
- @sdk_blocker = sdk_blocker
12
11
  @semaphore = Mutex.new
13
12
  @telemetry_runtime_producer = telemetry_runtime_producer
14
13
  end
@@ -40,13 +39,11 @@ module SplitIoClient
40
39
 
41
40
  @config.logger.debug("segments seen(#{data[:segment_names].length}): #{data[:segment_names].to_a}") if @config.debug_enabled
42
41
 
43
- @sdk_blocker.splits_ready!
44
-
45
- data[:segment_names]
42
+ { segment_names: data[:segment_names], success: true }
46
43
  end
47
44
  rescue StandardError => error
48
45
  @config.log_found_exception(__method__.to_s, error)
49
- []
46
+ { segment_names: [], success: false }
50
47
  end
51
48
 
52
49
  def stop_splits_thread
@@ -7,10 +7,10 @@ module SplitIoClient
7
7
  require 'yaml'
8
8
  attr_reader :splits_repository
9
9
 
10
- def initialize(splits_repository, config, sdk_blocker = nil)
10
+ def initialize(splits_repository, config, status_manager = nil)
11
11
  @splits_repository = splits_repository
12
12
  @config = config
13
- @sdk_blocker = sdk_blocker
13
+ @status_manager = status_manager
14
14
  end
15
15
 
16
16
  def call
@@ -45,10 +45,7 @@ module SplitIoClient
45
45
  store_split(split)
46
46
  end
47
47
 
48
- if @sdk_blocker
49
- @sdk_blocker.splits_ready!
50
- @sdk_blocker.segments_ready!
51
- end
48
+ @status_manager.ready! if @status_manager
52
49
  rescue StandardError => error
53
50
  @config.logger.error('Error while parsing the split file. ' \
54
51
  'Check that the input file matches the expected format')
@@ -14,13 +14,13 @@ module SplitIoClient
14
14
  # @param api_key [String] the API key for your split account
15
15
  #
16
16
  # @return [SplitIoClient] split.io client instance
17
- def initialize(api_key, repositories, sdk_blocker, config, impressions_manager, telemetry_evaluation_producer)
17
+ def initialize(api_key, repositories, status_manager, config, impressions_manager, telemetry_evaluation_producer)
18
18
  @api_key = api_key
19
19
  @splits_repository = repositories[:splits]
20
20
  @segments_repository = repositories[:segments]
21
21
  @impressions_repository = repositories[:impressions]
22
22
  @events_repository = repositories[:events]
23
- @sdk_blocker = sdk_blocker
23
+ @status_manager = status_manager
24
24
  @destroyed = false
25
25
  @config = config
26
26
  @impressions_manager = impressions_manager
@@ -137,7 +137,7 @@ module SplitIoClient
137
137
  else
138
138
  {
139
139
  treatment: treatment_data[:treatment],
140
- config: treatment_data[:config]
140
+ config: treatment_data[:config],
141
141
  }
142
142
  end
143
143
  end
@@ -157,7 +157,7 @@ module SplitIoClient
157
157
  end
158
158
 
159
159
  def block_until_ready(time = nil)
160
- @sdk_blocker.block(time) if @sdk_blocker && !@sdk_blocker.ready?
160
+ @status_manager.wait_until_ready(time) if @status_manager
161
161
  end
162
162
 
163
163
  private
@@ -310,7 +310,7 @@ module SplitIoClient
310
310
  end
311
311
 
312
312
  def ready?
313
- return @sdk_blocker.ready? if @sdk_blocker
313
+ return @status_manager.ready? if @status_manager
314
314
  true
315
315
  end
316
316
 
@@ -21,8 +21,8 @@ module SplitIoClient
21
21
  @impression_counter.inc(split_name, impression_data[:m]) if optimized? && !redis?
22
22
 
23
23
  impression(impression_data, params[:attributes])
24
- rescue StandardError => error
25
- @config.log_found_exception(__method__.to_s, error)
24
+ rescue StandardError => e
25
+ @config.log_found_exception(__method__.to_s, e)
26
26
  end
27
27
 
28
28
  def track(impressions)
@@ -48,8 +48,8 @@ module SplitIoClient
48
48
  end
49
49
 
50
50
  record_stats(queued, dropped, dedupe)
51
- rescue StandardError => error
52
- @config.log_found_exception(__method__.to_s, error)
51
+ rescue StandardError => e
52
+ @config.log_found_exception(__method__.to_s, e)
53
53
  end
54
54
 
55
55
  private
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SplitIoClient
4
+ module Engine
5
+ class StatusManager
6
+ def initialize(config)
7
+ @config = config
8
+ @sdk_ready = Concurrent::CountDownLatch.new(1)
9
+ end
10
+
11
+ def ready?
12
+ return true if @config.consumer?
13
+
14
+ @sdk_ready.wait(0)
15
+ end
16
+
17
+ def ready!
18
+ return if ready?
19
+
20
+ @sdk_ready.count_down
21
+ @config.logger.info('SplitIO SDK is ready')
22
+ end
23
+
24
+ def wait_until_ready(seconds = nil)
25
+ return if @config.consumer?
26
+
27
+ timeout = seconds || @config.block_until_ready
28
+
29
+ raise SDKBlockerTimeoutExpiredException, 'SDK start up timeout expired' unless @sdk_ready.wait(timeout)
30
+ end
31
+ end
32
+ end
33
+ end
@@ -12,8 +12,8 @@ module SplitIoClient
12
12
  config,
13
13
  synchronizer,
14
14
  telemetry_runtime_producer,
15
- sdk_blocker,
16
- telemetry_synchronizer
15
+ telemetry_synchronizer,
16
+ status_manager
17
17
  )
18
18
  @synchronizer = synchronizer
19
19
  notification_manager_keeper = SSE::NotificationManagerKeeper.new(config, telemetry_runtime_producer) do |manager|
@@ -33,55 +33,41 @@ module SplitIoClient
33
33
  @sse_connected = Concurrent::AtomicBoolean.new(false)
34
34
  @config = config
35
35
  @telemetry_runtime_producer = telemetry_runtime_producer
36
- @sdk_blocker = sdk_blocker
37
36
  @telemetry_synchronizer = telemetry_synchronizer
37
+ @status_manager = status_manager
38
38
  end
39
39
 
40
40
  def start
41
- if @config.streaming_enabled
42
- start_stream
43
- start_stream_forked if defined?(PhusionPassenger)
44
- elsif @config.standalone?
45
- start_poll
46
- end
47
-
48
- synchronize_telemetry_config
41
+ start_thread
42
+ PhusionPassenger.on_event(:starting_worker_process) { |forked| start_thread if forked } if defined?(PhusionPassenger)
49
43
  end
50
44
 
51
45
  private
52
46
 
53
- # Starts tasks if stream is enabled.
54
- def start_stream
55
- @config.logger.debug('Starting push mode ...')
56
- @synchronizer.sync_all
57
- @synchronizer.start_periodic_data_recording
58
-
59
- start_sse_connection_thread
60
- end
47
+ def start_thread
48
+ @config.threads[:start_sdk] = Thread.new do
49
+ sleep(0.5) until @synchronizer.sync_all(false)
61
50
 
62
- def start_poll
63
- @config.logger.debug('Starting polling mode ...')
64
- @synchronizer.start_periodic_fetch
65
- @synchronizer.start_periodic_data_recording
66
- record_telemetry(Telemetry::Domain::Constants::SYNC_MODE, SYNC_MODE_POLLING)
67
- rescue StandardError => e
68
- @config.logger.error("start_poll error : #{e.inspect}")
69
- end
51
+ @status_manager.ready!
52
+ @telemetry_synchronizer.synchronize_config
53
+ @synchronizer.start_periodic_data_recording
54
+ connected = false
70
55
 
71
- # Starts thread which connect to sse and after that fetch splits and segments once.
72
- def start_sse_connection_thread
73
- @config.threads[:sync_manager_start_sse] = Thread.new do
74
- begin
56
+ if @config.streaming_enabled
57
+ @config.logger.debug('Starting Straming mode ...')
75
58
  connected = @push_manager.start_sse
76
- @synchronizer.start_periodic_fetch unless connected
77
- rescue StandardError => e
78
- @config.logger.error("start_sse_connection_thread error : #{e.inspect}")
59
+
60
+ if defined?(PhusionPassenger)
61
+ PhusionPassenger.on_event(:starting_worker_process) { |forked| sse_thread_forked if forked }
62
+ end
79
63
  end
80
- end
81
- end
82
64
 
83
- def start_stream_forked
84
- PhusionPassenger.on_event(:starting_worker_process) { |forked| start_stream if forked }
65
+ unless connected
66
+ @config.logger.debug('Starting polling mode ...')
67
+ @synchronizer.start_periodic_fetch
68
+ record_telemetry(Telemetry::Domain::Constants::SYNC_MODE, SYNC_MODE_POLLING)
69
+ end
70
+ end
85
71
  end
86
72
 
87
73
  def process_action(action)
@@ -165,16 +151,9 @@ module SplitIoClient
165
151
  @telemetry_runtime_producer.record_streaming_event(type, data)
166
152
  end
167
153
 
168
- def synchronize_telemetry_config
169
- @config.threads[:telemetry_config_sender] = Thread.new do
170
- begin
171
- @sdk_blocker.wait_unitil_internal_ready unless @config.consumer?
172
- @telemetry_synchronizer.synchronize_config
173
- rescue SplitIoClient::SDKShutdownException
174
- @telemetry_synchronizer.synchronize_config
175
- @config.logger.info('Posting Telemetry config due to shutdown')
176
- end
177
- end
154
+ def sse_thread_forked
155
+ connected = @push_manager.start_sse
156
+ @synchronizer.start_periodic_fetch unless connected
178
157
  end
179
158
  end
180
159
  end
@@ -14,7 +14,6 @@ module SplitIoClient
14
14
  repositories,
15
15
  api_key,
16
16
  config,
17
- sdk_blocker,
18
17
  params
19
18
  )
20
19
  @splits_repository = repositories[:splits]
@@ -23,7 +22,6 @@ module SplitIoClient
23
22
  @events_repository = repositories[:events]
24
23
  @api_key = api_key
25
24
  @config = config
26
- @sdk_blocker = sdk_blocker
27
25
  @split_fetcher = params[:split_fetcher]
28
26
  @segment_fetcher = params[:segment_fetcher]
29
27
  @impressions_api = SplitIoClient::Api::Impressions.new(@api_key, @config, params[:telemetry_runtime_producer])
@@ -31,12 +29,16 @@ module SplitIoClient
31
29
  @telemetry_synchronizer = params[:telemetry_synchronizer]
32
30
  end
33
31
 
34
- def sync_all
32
+ def sync_all(asynchronous = true)
33
+ unless asynchronous
34
+ return sync_splits_and_segments
35
+ end
36
+
35
37
  @config.threads[:sync_all_thread] = Thread.new do
36
- @config.logger.debug('Synchronizing Splits and Segments ...') if @config.debug_enabled
37
- @split_fetcher.fetch_splits
38
- @segment_fetcher.fetch_segments
38
+ sync_splits_and_segments
39
39
  end
40
+
41
+ true
40
42
  end
41
43
 
42
44
  def start_periodic_data_recording
@@ -82,7 +84,7 @@ module SplitIoClient
82
84
  nil,
83
85
  true)
84
86
 
85
- attempts = @config.on_demand_fetch_max_retries - result[:remaining_attempts]
87
+ attempts = ON_DEMAND_FETCH_BACKOFF_MAX_RETRIES - result[:remaining_attempts]
86
88
 
87
89
  if result[:success]
88
90
  @segment_fetcher.fetch_segments_if_not_exists(result[:segment_names], true) unless result[:segment_names].empty?
@@ -156,20 +158,16 @@ module SplitIoClient
156
158
  loop do
157
159
  remaining_attempts -= 1
158
160
 
159
- segment_names = @split_fetcher.fetch_splits(fetch_options)
161
+ result = @split_fetcher.fetch_splits(fetch_options)
160
162
 
161
- return sync_result(true, remaining_attempts, segment_names) if target_cn <= @splits_repository.get_change_number
162
- return sync_result(false, remaining_attempts, segment_names) if remaining_attempts <= 0
163
+ return sync_result(true, remaining_attempts, result[:segment_names]) if target_cn <= @splits_repository.get_change_number
164
+ return sync_result(false, remaining_attempts, result[:segment_names]) if remaining_attempts <= 0
163
165
 
164
166
  delay = with_backoff ? backoff.interval : retry_delay_seconds
165
167
  sleep(delay)
166
168
  end
167
169
  end
168
170
 
169
- def fetch_segments
170
- @segment_fetcher.fetch_segments
171
- end
172
-
173
171
  # Starts thread which loops constantly and sends impressions to the Split API
174
172
  def impressions_sender
175
173
  ImpressionsSender.new(@impressions_repository, @config, @impressions_api).call
@@ -192,6 +190,13 @@ module SplitIoClient
192
190
  def sync_result(success, remaining_attempts, segment_names = nil)
193
191
  { success: success, remaining_attempts: remaining_attempts, segment_names: segment_names }
194
192
  end
193
+
194
+ def sync_splits_and_segments
195
+ @config.logger.debug('Synchronizing Splits and Segments ...') if @config.debug_enabled
196
+ splits_result = @split_fetcher.fetch_splits
197
+
198
+ splits_result[:success] && @segment_fetcher.fetch_segments
199
+ end
195
200
  end
196
201
  end
197
202
  end
@@ -4,9 +4,9 @@ module SplitIoClient
4
4
  # Creates a new split manager instance that connects to split.io API.
5
5
  #
6
6
  # @return [SplitIoManager] split.io client instance
7
- def initialize(splits_repository = nil, sdk_blocker, config)
7
+ def initialize(splits_repository = nil, status_manager, config)
8
8
  @splits_repository = splits_repository
9
- @sdk_blocker = sdk_blocker
9
+ @status_manager = status_manager
10
10
  @config = config
11
11
  end
12
12
 
@@ -78,7 +78,7 @@ module SplitIoClient
78
78
  end
79
79
 
80
80
  def block_until_ready(time = nil)
81
- @sdk_blocker.block(time) if @sdk_blocker && !@sdk_blocker.ready?
81
+ @status_manager.wait_until_ready(time) if @status_manager
82
82
  end
83
83
 
84
84
  private
@@ -111,7 +111,7 @@ module SplitIoClient
111
111
 
112
112
  # move to blocker, alongside block until ready to avoid duplication
113
113
  def ready?
114
- return @sdk_blocker.ready? if @sdk_blocker
114
+ return @status_manager.ready? if @status_manager
115
115
  true
116
116
  end
117
117
  end
@@ -28,45 +28,49 @@ module SplitIoClient
28
28
 
29
29
  raise 'Invalid SDK mode' unless valid_mode
30
30
 
31
+ validate_api_key
32
+
33
+ register_factory
34
+
31
35
  build_telemetry_components
32
36
 
33
37
  @splits_repository = SplitsRepository.new(@config)
34
38
  @segments_repository = SegmentsRepository.new(@config)
35
39
  @impressions_repository = ImpressionsRepository.new(@config)
36
40
  @events_repository = EventsRepository.new(@config, @api_key, @runtime_producer)
37
- @sdk_blocker = SDKBlocker.new(@splits_repository, @segments_repository, @config)
38
41
  @impression_counter = SplitIoClient::Engine::Common::ImpressionCounter.new
39
42
  @impressions_manager = SplitIoClient::Engine::Common::ImpressionManager.new(@config, @impressions_repository, @impression_counter, @runtime_producer)
40
43
  @telemetry_api = SplitIoClient::Api::TelemetryApi.new(@config, @api_key, @runtime_producer)
41
44
  @telemetry_synchronizer = Telemetry::Synchronizer.new(@config, @telemetry_consumers, @init_producer, repositories, @telemetry_api)
45
+ @status_manager = Engine::StatusManager.new(@config)
42
46
 
43
47
  start!
44
48
 
45
- @client = SplitClient.new(@api_key, repositories, @sdk_blocker, @config, @impressions_manager, @evaluation_producer)
46
- @manager = SplitManager.new(@splits_repository, @sdk_blocker, @config)
47
-
48
- validate_api_key
49
-
50
- register_factory
49
+ @client = SplitClient.new(@api_key, repositories, @status_manager, @config, @impressions_manager, @evaluation_producer)
50
+ @manager = SplitManager.new(@splits_repository, @status_manager, @config)
51
51
  end
52
52
 
53
53
  def start!
54
- if @config.localhost_mode
55
- start_localhost_components
56
- else
57
- split_fetcher = SplitFetcher.new(@splits_repository, @api_key, config, @sdk_blocker, @runtime_producer)
58
- segment_fetcher = SegmentFetcher.new(@segments_repository, @api_key, config, @sdk_blocker, @runtime_producer)
59
- params = {
60
- split_fetcher: split_fetcher,
61
- segment_fetcher: segment_fetcher,
62
- imp_counter: @impression_counter,
63
- telemetry_runtime_producer: @runtime_producer,
64
- telemetry_synchronizer: @telemetry_synchronizer
65
- }
66
-
67
- synchronizer = SplitIoClient::Engine::Synchronizer.new(repositories, @api_key, @config, @sdk_blocker, params)
68
- SplitIoClient::Engine::SyncManager.new(repositories, @api_key, @config, synchronizer, @runtime_producer, @sdk_blocker, @telemetry_synchronizer).start
54
+ return start_localhost_components if @config.localhost_mode
55
+
56
+ if @config.consumer?
57
+ @status_manager.ready!
58
+ @telemetry_synchronizer.synchronize_config
59
+ return
69
60
  end
61
+
62
+ split_fetcher = SplitFetcher.new(@splits_repository, @api_key, config, @runtime_producer)
63
+ segment_fetcher = SegmentFetcher.new(@segments_repository, @api_key, config, @runtime_producer)
64
+ params = {
65
+ split_fetcher: split_fetcher,
66
+ segment_fetcher: segment_fetcher,
67
+ imp_counter: @impression_counter,
68
+ telemetry_runtime_producer: @runtime_producer,
69
+ telemetry_synchronizer: @telemetry_synchronizer
70
+ }
71
+
72
+ synchronizer = SplitIoClient::Engine::Synchronizer.new(repositories, @api_key, @config, params)
73
+ SplitIoClient::Engine::SyncManager.new(repositories, @api_key, @config, synchronizer, @runtime_producer, @telemetry_synchronizer, @status_manager).start
70
74
  end
71
75
 
72
76
  def stop!
@@ -145,7 +149,7 @@ module SplitIoClient
145
149
  end
146
150
 
147
151
  def start_localhost_components
148
- LocalhostSplitStore.new(@splits_repository, @config, @sdk_blocker).call
152
+ LocalhostSplitStore.new(@splits_repository, @config, @status_manager).call
149
153
 
150
154
  # Starts thread which loops constantly and cleans up repositories to avoid memory issues in localhost mode
151
155
  LocalhostRepoCleaner.new(@impressions_repository, @events_repository, @config).call
@@ -77,7 +77,7 @@ module SplitIoClient
77
77
  end
78
78
 
79
79
  def connect_stream(latch)
80
- socket_write
80
+ socket_write(latch)
81
81
 
82
82
  while connected? || @first_event.value
83
83
  begin
@@ -96,13 +96,14 @@ module SplitIoClient
96
96
  end
97
97
  end
98
98
 
99
- def socket_write
99
+ def socket_write(latch)
100
100
  @first_event.make_true
101
101
  @socket = socket_connect
102
102
  @socket.write(build_request(@uri))
103
103
  rescue StandardError => e
104
104
  @config.logger.error("Error during connecting to #{@uri.host}. Error: #{e.inspect}")
105
105
  close(Constants::PUSH_NONRETRYABLE_ERROR)
106
+ latch.count_down
106
107
  end
107
108
 
108
109
  def read_first_event(data, latch)
@@ -33,8 +33,8 @@ module SplitIoClient
33
33
 
34
34
  TREATMENT = 'treatment'
35
35
  TREATMENTS = 'treatments'
36
- TREATMENT_WITH_CONFIG = 'treatment_with_config'
37
- TREATMENTS_WITH_CONFIG = 'treatments_with_config'
36
+ TREATMENT_WITH_CONFIG = 'treatmentWithConfig'
37
+ TREATMENTS_WITH_CONFIG = 'treatmentsWithConfig'
38
38
  TRACK = 'track'
39
39
  end
40
40
  end
@@ -14,14 +14,14 @@ module SplitIoClient
14
14
 
15
15
  def record_latency(method, bucket)
16
16
  @adapter.hincrby(latency_key, "#{@sdk_version}/#{@name}/#{@ip}/#{method}/#{bucket}", 1)
17
- rescue StandardError => error
18
- @config.log_found_exception(__method__.to_s, error)
17
+ rescue StandardError => e
18
+ @config.log_found_exception(__method__.to_s, e)
19
19
  end
20
20
 
21
21
  def record_exception(method)
22
22
  @adapter.hincrby(exception_key, "#{@sdk_version}/#{@name}/#{@ip}/#{method}", 1)
23
- rescue StandardError => error
24
- @config.log_found_exception(__method__.to_s, error)
23
+ rescue StandardError => e
24
+ @config.log_found_exception(__method__.to_s, e)
25
25
  end
26
26
 
27
27
  private
@@ -1,3 +1,3 @@
1
1
  module SplitIoClient
2
- VERSION = '7.3.1.pre.rc1'
2
+ VERSION = '7.3.2'
3
3
  end
@@ -28,10 +28,9 @@ require 'splitclient-rb/cache/senders/impressions_sender'
28
28
  require 'splitclient-rb/cache/senders/events_sender'
29
29
  require 'splitclient-rb/cache/senders/impressions_count_sender'
30
30
  require 'splitclient-rb/cache/senders/localhost_repo_cleaner'
31
- require 'splitclient-rb/cache/stores/store_utils'
32
31
  require 'splitclient-rb/cache/stores/localhost_split_builder'
33
- require 'splitclient-rb/cache/stores/sdk_blocker'
34
32
  require 'splitclient-rb/cache/stores/localhost_split_store'
33
+ require 'splitclient-rb/cache/stores/store_utils'
35
34
 
36
35
  require 'splitclient-rb/clients/split_client'
37
36
  require 'splitclient-rb/managers/split_manager'
@@ -87,6 +86,7 @@ require 'splitclient-rb/engine/models/treatment'
87
86
  require 'splitclient-rb/engine/auth_api_client'
88
87
  require 'splitclient-rb/engine/back_off'
89
88
  require 'splitclient-rb/engine/push_manager'
89
+ require 'splitclient-rb/engine/status_manager'
90
90
  require 'splitclient-rb/engine/sync_manager'
91
91
  require 'splitclient-rb/engine/synchronizer'
92
92
  require 'splitclient-rb/utilitites'
@@ -38,14 +38,15 @@ Gem::Specification.new do |spec|
38
38
 
39
39
  spec.add_development_dependency 'allocation_stats'
40
40
  spec.add_development_dependency 'appraisal'
41
- spec.add_development_dependency 'bundler', '~> 1.11'
41
+ spec.add_development_dependency 'bundler', '~> 2.2'
42
42
  spec.add_development_dependency 'pry'
43
43
  spec.add_development_dependency 'pry-nav'
44
44
  spec.add_development_dependency 'rake', '12.3.3'
45
45
  spec.add_development_dependency 'rake-compiler'
46
46
  spec.add_development_dependency 'rspec'
47
47
  spec.add_development_dependency 'rubocop', '0.59.0'
48
- spec.add_development_dependency 'simplecov'
48
+ spec.add_development_dependency 'simplecov', '0.20.0'
49
+ spec.add_development_dependency 'simplecov-json'
49
50
  spec.add_development_dependency 'timecop'
50
51
  spec.add_development_dependency 'webmock'
51
52
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: splitclient-rb
3
3
  version: !ruby/object:Gem::Version
4
- version: 7.3.1.pre.rc1
4
+ version: 7.3.2
5
5
  platform: java
6
6
  authors:
7
7
  - Split Software
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-07-22 00:00:00.000000000 Z
11
+ date: 2021-12-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  requirement: !ruby/object:Gem::Requirement
@@ -43,7 +43,7 @@ dependencies:
43
43
  requirements:
44
44
  - - "~>"
45
45
  - !ruby/object:Gem::Version
46
- version: '1.11'
46
+ version: '2.2'
47
47
  name: bundler
48
48
  prerelease: false
49
49
  type: :development
@@ -51,7 +51,7 @@ dependencies:
51
51
  requirements:
52
52
  - - "~>"
53
53
  - !ruby/object:Gem::Version
54
- version: '1.11'
54
+ version: '2.2'
55
55
  - !ruby/object:Gem::Dependency
56
56
  requirement: !ruby/object:Gem::Requirement
57
57
  requirements:
@@ -136,13 +136,27 @@ dependencies:
136
136
  - - '='
137
137
  - !ruby/object:Gem::Version
138
138
  version: 0.59.0
139
+ - !ruby/object:Gem::Dependency
140
+ requirement: !ruby/object:Gem::Requirement
141
+ requirements:
142
+ - - '='
143
+ - !ruby/object:Gem::Version
144
+ version: 0.20.0
145
+ name: simplecov
146
+ prerelease: false
147
+ type: :development
148
+ version_requirements: !ruby/object:Gem::Requirement
149
+ requirements:
150
+ - - '='
151
+ - !ruby/object:Gem::Version
152
+ version: 0.20.0
139
153
  - !ruby/object:Gem::Dependency
140
154
  requirement: !ruby/object:Gem::Requirement
141
155
  requirements:
142
156
  - - ">="
143
157
  - !ruby/object:Gem::Version
144
158
  version: '0'
145
- name: simplecov
159
+ name: simplecov-json
146
160
  prerelease: false
147
161
  type: :development
148
162
  version_requirements: !ruby/object:Gem::Requirement
@@ -312,10 +326,10 @@ extensions: []
312
326
  extra_rdoc_files: []
313
327
  files:
314
328
  - ".github/pull_request_template.md"
329
+ - ".github/workflows/ci.yml"
315
330
  - ".gitignore"
316
331
  - ".rubocop.yml"
317
332
  - ".simplecov"
318
- - ".travis.yml"
319
333
  - Appraisals
320
334
  - CHANGES.txt
321
335
  - CONTRIBUTORS-GUIDE.md
@@ -356,7 +370,6 @@ files:
356
370
  - lib/splitclient-rb/cache/senders/localhost_repo_cleaner.rb
357
371
  - lib/splitclient-rb/cache/stores/localhost_split_builder.rb
358
372
  - lib/splitclient-rb/cache/stores/localhost_split_store.rb
359
- - lib/splitclient-rb/cache/stores/sdk_blocker.rb
360
373
  - lib/splitclient-rb/cache/stores/store_utils.rb
361
374
  - lib/splitclient-rb/clients/split_client.rb
362
375
  - lib/splitclient-rb/constants.rb
@@ -403,6 +416,7 @@ files:
403
416
  - lib/splitclient-rb/engine/parser/evaluator.rb
404
417
  - lib/splitclient-rb/engine/parser/partition.rb
405
418
  - lib/splitclient-rb/engine/push_manager.rb
419
+ - lib/splitclient-rb/engine/status_manager.rb
406
420
  - lib/splitclient-rb/engine/sync_manager.rb
407
421
  - lib/splitclient-rb/engine/synchronizer.rb
408
422
  - lib/splitclient-rb/exceptions.rb
@@ -446,7 +460,6 @@ files:
446
460
  - lib/splitclient-rb/utilitites.rb
447
461
  - lib/splitclient-rb/validators.rb
448
462
  - lib/splitclient-rb/version.rb
449
- - sonar-scanner.sh
450
463
  - splitclient-rb.gemspec
451
464
  - tasks/benchmark_get_treatment.rake
452
465
  - tasks/irb.rake
@@ -465,9 +478,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
465
478
  version: '0'
466
479
  required_rubygems_version: !ruby/object:Gem::Requirement
467
480
  requirements:
468
- - - ">"
481
+ - - ">="
469
482
  - !ruby/object:Gem::Version
470
- version: 1.3.1
483
+ version: '0'
471
484
  requirements: []
472
485
  rubyforge_project:
473
486
  rubygems_version: 2.6.14
data/.travis.yml DELETED
@@ -1,20 +0,0 @@
1
- language: ruby
2
-
3
- rvm:
4
- - "2.3.6"
5
-
6
- services:
7
- - redis-server
8
-
9
- addons:
10
- sonarqube: true
11
-
12
- git:
13
- depth: false
14
-
15
- before_install:
16
- - gem uninstall -v '>= 2' -i $(rvm gemdir)@global -ax bundler || true
17
- - gem install bundler -v '< 2'
18
-
19
- after_success:
20
- - bash sonar-scanner.sh
@@ -1,64 +0,0 @@
1
- require 'thread'
2
- require 'timeout'
3
-
4
- module SplitIoClient
5
- module Cache
6
- module Stores
7
- class SDKBlocker
8
- attr_reader :splits_repository
9
-
10
- def initialize(splits_repository, segments_repository, config)
11
- @splits_repository = splits_repository
12
- @segments_repository = segments_repository
13
- @config = config
14
- @internal_ready = Concurrent::CountDownLatch.new(1)
15
-
16
- if @config.standalone?
17
- @splits_repository.not_ready!
18
- @segments_repository.not_ready!
19
- end
20
- end
21
-
22
- def splits_ready!
23
- if !ready?
24
- @splits_repository.ready!
25
- @config.logger.info('splits are ready')
26
- end
27
- end
28
-
29
- def segments_ready!
30
- if !ready?
31
- @segments_repository.ready!
32
- @config.logger.info('segments are ready')
33
- end
34
- end
35
-
36
- def block(time = nil)
37
- begin
38
- timeout = time || @config.block_until_ready
39
- Timeout::timeout(timeout) do
40
- sleep 0.1 until ready?
41
- end
42
- rescue Timeout::Error
43
- fail SDKBlockerTimeoutExpiredException, 'SDK start up timeout expired'
44
- end
45
-
46
- @config.logger.info('SplitIO SDK is ready')
47
- end
48
-
49
- def ready?
50
- return true if @config.consumer?
51
- @splits_repository.ready? && @segments_repository.ready?
52
- end
53
-
54
- def sdk_internal_ready
55
- @internal_ready.count_down
56
- end
57
-
58
- def wait_unitil_internal_ready
59
- @internal_ready.wait
60
- end
61
- end
62
- end
63
- end
64
- end
data/sonar-scanner.sh DELETED
@@ -1,42 +0,0 @@
1
- #/bin/bash -e
2
-
3
- sonar_scanner() {
4
- local params=$@
5
-
6
- sonar-scanner \
7
- -Dsonar.host.url='https://sonarqube.split-internal.com' \
8
- -Dsonar.login="$SONAR_TOKEN" \
9
- -Dsonar.ws.timeout='300' \
10
- -Dsonar.sources='lib' \
11
- -Dsonar.projectName='ruby-client' \
12
- -Dsonar.projectKey='ruby-client' \
13
- -Dsonar.ruby.coverage.reportPaths='coverage/.resultset.json' \
14
- -Dsonar.links.ci='https://travis-ci.com/splitio/ruby-client' \
15
- -Dsonar.links.scm='https://github.com/splitio/ruby-client' \
16
- ${params}
17
-
18
- return $?
19
- }
20
-
21
- if [ "$TRAVIS_PULL_REQUEST" != "false" ]; then
22
- sonar_scanner \
23
- -Dsonar.pullrequest.provider='GitHub' \
24
- -Dsonar.pullrequest.github.repository='splitio/ruby-client' \
25
- -Dsonar.pullrequest.key=$TRAVIS_PULL_REQUEST \
26
- -Dsonar.pullrequest.branch=$TRAVIS_PULL_REQUEST_BRANCH \
27
- -Dsonar.pullrequest.base=$TRAVIS_BRANCH
28
- else
29
- if [ "$TRAVIS_BRANCH" == 'master' ]; then
30
- sonar_scanner \
31
- -Dsonar.branch.name=$TRAVIS_BRANCH
32
- else
33
- if [ "$TRAVIS_BRANCH" == 'development' ]; then
34
- TARGET_BRANCH='master'
35
- else
36
- TARGET_BRANCH='development'
37
- fi
38
- sonar_scanner \
39
- -Dsonar.branch.name=$TRAVIS_BRANCH \
40
- -Dsonar.branch.target=$TARGET_BRANCH
41
- fi
42
- fi