splitclient-rb 7.3.0.pre.rc2-java → 7.3.2-java
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/ci.yml +78 -0
- data/.rubocop.yml +3 -0
- data/CHANGES.txt +11 -0
- data/LICENSE +1 -1
- data/README.md +1 -1
- data/lib/splitclient-rb/cache/fetchers/segment_fetcher.rb +10 -13
- data/lib/splitclient-rb/cache/fetchers/split_fetcher.rb +7 -9
- data/lib/splitclient-rb/cache/stores/localhost_split_store.rb +3 -6
- data/lib/splitclient-rb/clients/split_client.rb +5 -5
- data/lib/splitclient-rb/engine/api/segments.rb +8 -4
- data/lib/splitclient-rb/engine/api/splits.rb +5 -3
- data/lib/splitclient-rb/engine/back_off.rb +26 -0
- data/lib/splitclient-rb/engine/common/impressions_manager.rb +4 -4
- data/lib/splitclient-rb/engine/push_manager.rb +1 -1
- data/lib/splitclient-rb/engine/status_manager.rb +33 -0
- data/lib/splitclient-rb/engine/sync_manager.rb +27 -48
- data/lib/splitclient-rb/engine/synchronizer.rb +124 -14
- data/lib/splitclient-rb/managers/split_manager.rb +4 -4
- data/lib/splitclient-rb/split_config.rb +14 -0
- data/lib/splitclient-rb/split_factory.rb +27 -23
- data/lib/splitclient-rb/sse/event_source/client.rb +3 -2
- data/lib/splitclient-rb/sse/workers/segments_worker.rb +1 -5
- data/lib/splitclient-rb/sse/workers/splits_worker.rb +1 -8
- data/lib/splitclient-rb/telemetry/domain/constants.rb +2 -2
- data/lib/splitclient-rb/telemetry/redis/redis_evaluation_producer.rb +4 -4
- data/lib/splitclient-rb/version.rb +1 -1
- data/lib/splitclient-rb.rb +4 -4
- data/splitclient-rb.gemspec +3 -2
- metadata +24 -11
- data/.travis.yml +0 -20
- data/lib/splitclient-rb/cache/stores/sdk_blocker.rb +0 -64
- data/lib/splitclient-rb/sse/event_source/back_off.rb +0 -25
- data/sonar-scanner.sh +0 -42
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7237dc328456c0eb3c6db4d51baba65df84f5d41
|
4
|
+
data.tar.gz: f4e1859a0014c14fa7fdbf81f0cc472e2cc6a99e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
@@ -31,6 +31,7 @@ Metrics/LineLength:
|
|
31
31
|
- spec/engine/sync_manager_spec.rb
|
32
32
|
- spec/engine/auth_api_client_spec.rb
|
33
33
|
- spec/telemetry/synchronizer_spec.rb
|
34
|
+
- spec/splitclient/split_config_spec.rb
|
34
35
|
|
35
36
|
Style/BracesAroundHashParameters:
|
36
37
|
Exclude:
|
@@ -62,3 +63,5 @@ AllCops:
|
|
62
63
|
- lib/splitclient-rb/engine/models/**/*
|
63
64
|
- lib/splitclient-rb/engine/parser/**/*
|
64
65
|
- spec/telemetry/synchronizer_spec.rb
|
66
|
+
- lib/splitclient-rb/engine/synchronizer.rb
|
67
|
+
- tmp/**/*
|
data/CHANGES.txt
CHANGED
@@ -1,5 +1,16 @@
|
|
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
|
+
|
10
|
+
7.3.0 (Jul 12, 2021)
|
11
|
+
- Updated SDK telemetry storage, metrics and updater to be more effective and send less often.
|
12
|
+
- Fixed high cpu usage when api key is wrong.
|
13
|
+
|
3
14
|
7.2.3 (Feb 24, 2021)
|
4
15
|
- Fixed missing segment fetch after an SPLIT_UPDATE.
|
5
16
|
- Updated streaming logic to support multiregion.
|
data/LICENSE
CHANGED
data/README.md
CHANGED
@@ -63,7 +63,7 @@ Split has built and maintains SDKs for:
|
|
63
63
|
* Java [Github](https://github.com/splitio/java-client) [Docs](https://help.split.io/hc/en-us/articles/360020405151-Java-SDK)
|
64
64
|
* Javascript [Github](https://github.com/splitio/javascript-client) [Docs](https://help.split.io/hc/en-us/articles/360020448791-JavaScript-SDK)
|
65
65
|
* Node [Github](https://github.com/splitio/javascript-client) [Docs](https://help.split.io/hc/en-us/articles/360020564931-Node-js-SDK)
|
66
|
-
* .NET [Github](https://github.com/splitio
|
66
|
+
* .NET [Github](https://github.com/splitio/dotnet-client) [Docs](https://help.split.io/hc/en-us/articles/360020240172--NET-SDK)
|
67
67
|
* Ruby [Github](https://github.com/splitio/ruby-client) [Docs](https://help.split.io/hc/en-us/articles/360020673251-Ruby-SDK)
|
68
68
|
* PHP [Github](https://github.com/splitio/php-client) [Docs](https://help.split.io/hc/en-us/articles/360020350372-PHP-SDK)
|
69
69
|
* Python [Github](https://github.com/splitio/python-client) [Docs](https://help.split.io/hc/en-us/articles/360020359652-Python-SDK)
|
@@ -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,
|
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
|
@@ -30,16 +29,19 @@ module SplitIoClient
|
|
30
29
|
def fetch_segments_if_not_exists(names, cache_control_headers = false)
|
31
30
|
names.each do |name|
|
32
31
|
change_number = @segments_repository.get_change_number(name)
|
33
|
-
|
34
|
-
|
32
|
+
|
33
|
+
if change_number == -1
|
34
|
+
fetch_options = { cache_control_headers: cache_control_headers, till: nil }
|
35
|
+
fetch_segment(name, fetch_options) if change_number == -1
|
36
|
+
end
|
35
37
|
end
|
36
38
|
rescue StandardError => error
|
37
39
|
@config.log_found_exception(__method__.to_s, error)
|
38
40
|
end
|
39
41
|
|
40
|
-
def fetch_segment(name,
|
42
|
+
def fetch_segment(name, fetch_options = { cache_control_headers: false, till: nil })
|
41
43
|
@semaphore.synchronize do
|
42
|
-
segments_api.fetch_segments_by_names([name],
|
44
|
+
segments_api.fetch_segments_by_names([name], fetch_options)
|
43
45
|
end
|
44
46
|
rescue StandardError => error
|
45
47
|
@config.log_found_exception(__method__.to_s, error)
|
@@ -49,11 +51,11 @@ module SplitIoClient
|
|
49
51
|
@semaphore.synchronize do
|
50
52
|
segments_api.fetch_segments_by_names(@segments_repository.used_segment_names)
|
51
53
|
|
52
|
-
|
53
|
-
@sdk_blocker.sdk_internal_ready
|
54
|
+
true
|
54
55
|
end
|
55
56
|
rescue StandardError => error
|
56
57
|
@config.log_found_exception(__method__.to_s, error)
|
58
|
+
false
|
57
59
|
end
|
58
60
|
|
59
61
|
def stop_segments_thread
|
@@ -67,11 +69,6 @@ module SplitIoClient
|
|
67
69
|
@config.logger.info('Starting segments fetcher service') if @config.debug_enabled
|
68
70
|
|
69
71
|
loop do
|
70
|
-
unless @sdk_blocker.splits_repository.ready?
|
71
|
-
sleep 0.2
|
72
|
-
next
|
73
|
-
end
|
74
|
-
|
75
72
|
fetch_segments
|
76
73
|
@config.logger.debug("Segment names: #{@segments_repository.used_segment_names.to_a}") if @config.debug_enabled
|
77
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,
|
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
|
@@ -27,9 +26,9 @@ module SplitIoClient
|
|
27
26
|
end
|
28
27
|
end
|
29
28
|
|
30
|
-
def fetch_splits(
|
29
|
+
def fetch_splits(fetch_options = { cache_control_headers: false, till: nil })
|
31
30
|
@semaphore.synchronize do
|
32
|
-
data = splits_since(@splits_repository.get_change_number,
|
31
|
+
data = splits_since(@splits_repository.get_change_number, fetch_options)
|
33
32
|
|
34
33
|
data[:splits] && data[:splits].each do |split|
|
35
34
|
add_split_unless_archived(split)
|
@@ -40,12 +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
|
-
|
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)
|
46
|
+
{ segment_names: [], success: false }
|
49
47
|
end
|
50
48
|
|
51
49
|
def stop_splits_thread
|
@@ -67,8 +65,8 @@ module SplitIoClient
|
|
67
65
|
end
|
68
66
|
end
|
69
67
|
|
70
|
-
def splits_since(since,
|
71
|
-
splits_api.since(since,
|
68
|
+
def splits_since(since, fetch_options = { cache_control_headers: false, till: nil })
|
69
|
+
splits_api.since(since, fetch_options)
|
72
70
|
end
|
73
71
|
|
74
72
|
def add_split_unless_archived(split)
|
@@ -7,10 +7,10 @@ module SplitIoClient
|
|
7
7
|
require 'yaml'
|
8
8
|
attr_reader :splits_repository
|
9
9
|
|
10
|
-
def initialize(splits_repository, config,
|
10
|
+
def initialize(splits_repository, config, status_manager = nil)
|
11
11
|
@splits_repository = splits_repository
|
12
12
|
@config = config
|
13
|
-
@
|
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 @
|
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,
|
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
|
-
@
|
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
|
-
@
|
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 @
|
313
|
+
return @status_manager.ready? if @status_manager
|
314
314
|
true
|
315
315
|
end
|
316
316
|
|
@@ -11,13 +11,14 @@ module SplitIoClient
|
|
11
11
|
@telemetry_runtime_producer = telemetry_runtime_producer
|
12
12
|
end
|
13
13
|
|
14
|
-
def fetch_segments_by_names(names,
|
14
|
+
def fetch_segments_by_names(names, fetch_options = { cache_control_headers: false, till: nil })
|
15
15
|
return if names.nil? || names.empty?
|
16
16
|
|
17
17
|
names.each do |name|
|
18
18
|
since = @segments_repository.get_change_number(name)
|
19
|
+
|
19
20
|
loop do
|
20
|
-
segment = fetch_segment_changes(name, since,
|
21
|
+
segment = fetch_segment_changes(name, since, fetch_options)
|
21
22
|
@segments_repository.add_to_segment(segment)
|
22
23
|
|
23
24
|
@config.split_logger.log_if_debug("Segment #{name} fetched before: #{since}, \
|
@@ -32,9 +33,12 @@ module SplitIoClient
|
|
32
33
|
|
33
34
|
private
|
34
35
|
|
35
|
-
def fetch_segment_changes(name, since,
|
36
|
+
def fetch_segment_changes(name, since, fetch_options = { cache_control_headers: false, till: nil })
|
36
37
|
start = Time.now
|
37
|
-
|
38
|
+
|
39
|
+
params = { since: since }
|
40
|
+
params[:till] = fetch_options[:till] unless fetch_options[:till].nil?
|
41
|
+
response = get_api("#{@config.base_uri}/segmentChanges/#{name}", @api_key, params, fetch_options[:cache_control_headers])
|
38
42
|
|
39
43
|
if response.success?
|
40
44
|
segment = JSON.parse(response.body, symbolize_names: true)
|
@@ -10,10 +10,12 @@ module SplitIoClient
|
|
10
10
|
@telemetry_runtime_producer = telemetry_runtime_producer
|
11
11
|
end
|
12
12
|
|
13
|
-
def since(since,
|
13
|
+
def since(since, fetch_options = { cache_control_headers: false, till: nil })
|
14
14
|
start = Time.now
|
15
|
-
|
16
|
-
|
15
|
+
|
16
|
+
params = { since: since }
|
17
|
+
params[:till] = fetch_options[:till] unless fetch_options[:till].nil?
|
18
|
+
response = get_api("#{@config.base_uri}/splitChanges", @api_key, params, fetch_options[:cache_control_headers])
|
17
19
|
if response.success?
|
18
20
|
result = splits_with_segment_names(response.body)
|
19
21
|
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# frozen_string_literal: false
|
2
|
+
|
3
|
+
module SplitIoClient
|
4
|
+
module Engine
|
5
|
+
BACKOFF_MAX_ALLOWED = 1.8
|
6
|
+
class BackOff
|
7
|
+
def initialize(back_off_base, attempt = 0, max_allowed = BACKOFF_MAX_ALLOWED)
|
8
|
+
@attempt = attempt
|
9
|
+
@back_off_base = back_off_base
|
10
|
+
@max_allowed = max_allowed
|
11
|
+
end
|
12
|
+
|
13
|
+
def interval
|
14
|
+
interval = 0
|
15
|
+
interval = (@back_off_base * (2**@attempt)) if @attempt.positive?
|
16
|
+
@attempt += 1
|
17
|
+
|
18
|
+
interval >= @max_allowed ? @max_allowed : interval
|
19
|
+
end
|
20
|
+
|
21
|
+
def reset
|
22
|
+
@attempt = 0
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -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 =>
|
25
|
-
@config.log_found_exception(__method__.to_s,
|
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 =>
|
52
|
-
@config.log_found_exception(__method__.to_s,
|
51
|
+
rescue StandardError => e
|
52
|
+
@config.log_found_exception(__method__.to_s, e)
|
53
53
|
end
|
54
54
|
|
55
55
|
private
|
@@ -8,7 +8,7 @@ module SplitIoClient
|
|
8
8
|
@sse_handler = sse_handler
|
9
9
|
@auth_api_client = AuthApiClient.new(@config, telemetry_runtime_producer)
|
10
10
|
@api_key = api_key
|
11
|
-
@back_off =
|
11
|
+
@back_off = Engine::BackOff.new(@config.auth_retry_back_off_base, 1)
|
12
12
|
@telemetry_runtime_producer = telemetry_runtime_producer
|
13
13
|
end
|
14
14
|
|
@@ -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
|
-
|
16
|
-
|
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
|
-
|
42
|
-
|
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
|
-
|
54
|
-
|
55
|
-
|
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
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
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
|
-
|
72
|
-
|
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
|
-
|
77
|
-
|
78
|
-
|
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
|
-
|
84
|
-
|
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
|
169
|
-
|
170
|
-
|
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
|