splitclient-rb 7.3.0.pre.rc2-java → 7.3.2-java
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|