splitclient-rb 7.2.1-java → 7.2.3.pre.rc2-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/.rubocop.yml +3 -0
- data/CHANGES.txt +3 -0
- data/lib/splitclient-rb/cache/fetchers/segment_fetcher.rb +10 -2
- data/lib/splitclient-rb/cache/fetchers/split_fetcher.rb +2 -2
- data/lib/splitclient-rb/cache/senders/impressions_count_sender.rb +21 -21
- data/lib/splitclient-rb/constants.rb +6 -1
- data/lib/splitclient-rb/engine/push_manager.rb +2 -1
- data/lib/splitclient-rb/engine/sync_manager.rb +50 -33
- data/lib/splitclient-rb/engine/synchronizer.rb +4 -13
- data/lib/splitclient-rb/sse/event_source/client.rb +43 -27
- data/lib/splitclient-rb/sse/event_source/event_parser.rb +10 -1
- data/lib/splitclient-rb/sse/notification_manager_keeper.rb +30 -25
- data/lib/splitclient-rb/sse/sse_handler.rb +6 -15
- data/lib/splitclient-rb/sse/workers/segments_worker.rb +5 -4
- data/lib/splitclient-rb/sse/workers/splits_worker.rb +6 -3
- data/lib/splitclient-rb/version.rb +1 -1
- metadata +4 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 287f7f79723676d979a36e981d7aa7872eb10b77
|
4
|
+
data.tar.gz: 963b3062d4197614d6d36e48fb9fdd680c41bc34
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ee086221eb257722cd337b0c174271c926b249acfe60d96734a8b7da0314439c2cf44ada73df7a08dc19397f5bac8a5cf682dcf814767d343db5ad794793bbfb
|
7
|
+
data.tar.gz: 4fdefe428f8d4cfda3577d3fe79a0bc25bab342154b616b99cad81ed19b52e905269abae642f31ba188dbc5958caac002eae3948eb2f4dc5f19449bc46698d79
|
data/.rubocop.yml
CHANGED
data/CHANGES.txt
CHANGED
@@ -27,14 +27,22 @@ module SplitIoClient
|
|
27
27
|
end
|
28
28
|
end
|
29
29
|
|
30
|
+
def fetch_segments_if_not_exists(names)
|
31
|
+
names.each do |name|
|
32
|
+
change_number = @segments_repository.get_change_number(name)
|
33
|
+
|
34
|
+
fetch_segment(name) if change_number == -1
|
35
|
+
end
|
36
|
+
rescue StandardError => error
|
37
|
+
@config.log_found_exception(__method__.to_s, error)
|
38
|
+
end
|
39
|
+
|
30
40
|
def fetch_segment(name)
|
31
41
|
@semaphore.synchronize do
|
32
42
|
segments_api.fetch_segments_by_names([name])
|
33
|
-
true
|
34
43
|
end
|
35
44
|
rescue StandardError => error
|
36
45
|
@config.log_found_exception(__method__.to_s, error)
|
37
|
-
false
|
38
46
|
end
|
39
47
|
|
40
48
|
def fetch_segments
|
@@ -41,11 +41,11 @@ module SplitIoClient
|
|
41
41
|
@config.logger.debug("segments seen(#{data[:segment_names].length}): #{data[:segment_names].to_a}") if @config.debug_enabled
|
42
42
|
|
43
43
|
@sdk_blocker.splits_ready!
|
44
|
-
|
44
|
+
|
45
|
+
data[:segment_names]
|
45
46
|
end
|
46
47
|
rescue StandardError => error
|
47
48
|
@config.log_found_exception(__method__.to_s, error)
|
48
|
-
false
|
49
49
|
end
|
50
50
|
|
51
51
|
def stop_splits_thread
|
@@ -40,32 +40,32 @@ module SplitIoClient
|
|
40
40
|
@config.logger.info('Posting impressions count due to shutdown')
|
41
41
|
end
|
42
42
|
end
|
43
|
+
end
|
43
44
|
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
def formatter(counts)
|
51
|
-
return if counts.empty?
|
45
|
+
def post_impressions_count
|
46
|
+
@impressions_api.post_count(formatter(@impression_counter.pop_all))
|
47
|
+
rescue StandardError => error
|
48
|
+
@config.log_found_exception(__method__.to_s, error)
|
49
|
+
end
|
52
50
|
|
53
|
-
|
51
|
+
def formatter(counts)
|
52
|
+
return if counts.empty?
|
54
53
|
|
55
|
-
|
56
|
-
key_splited = key.split('::')
|
57
|
-
|
58
|
-
formated_counts[:pf] << {
|
59
|
-
f: key_splited[0].to_s, # feature name
|
60
|
-
m: key_splited[1].to_i, # time frame
|
61
|
-
rc: value # count
|
62
|
-
}
|
63
|
-
end
|
54
|
+
formated_counts = {pf: []}
|
64
55
|
|
65
|
-
|
66
|
-
|
67
|
-
|
56
|
+
counts.each do |key, value|
|
57
|
+
key_splited = key.split('::')
|
58
|
+
|
59
|
+
formated_counts[:pf] << {
|
60
|
+
f: key_splited[0].to_s, # feature name
|
61
|
+
m: key_splited[1].to_i, # time frame
|
62
|
+
rc: value # count
|
63
|
+
}
|
68
64
|
end
|
65
|
+
|
66
|
+
formated_counts
|
67
|
+
rescue StandardError => error
|
68
|
+
@config.log_found_exception(__method__.to_s, error)
|
69
69
|
end
|
70
70
|
end
|
71
71
|
end
|
@@ -6,5 +6,10 @@ class SplitIoClient::Constants
|
|
6
6
|
CONTROL_SEC = 'control_sec'
|
7
7
|
OCCUPANCY_CHANNEL_PREFIX = '[?occupancy=metrics.publishers]'
|
8
8
|
FETCH_BACK_OFF_BASE_RETRIES = 1
|
9
|
+
PUSH_CONNECTED = 'PUSH_CONNECTED'
|
10
|
+
PUSH_RETRYABLE_ERROR = 'PUSH_RETRYABLE_ERROR'
|
11
|
+
PUSH_NONRETRYABLE_ERROR = 'PUSH_NONRETRYABLE_ERROR'
|
12
|
+
PUSH_SUBSYSTEM_DOWN = 'PUSH_SUBSYSTEM_DOWN'
|
13
|
+
PUSH_SUBSYSTEM_READY = 'PUSH_SUBSYSTEM_READY'
|
14
|
+
PUSH_SUBSYSTEM_OFF = 'PUSH_SUBSYSTEM_OFF'
|
9
15
|
end
|
10
|
-
|
@@ -19,12 +19,13 @@ module SplitIoClient
|
|
19
19
|
if response[:push_enabled] && @sse_handler.start(response[:token], response[:channels])
|
20
20
|
schedule_next_token_refresh(response[:exp])
|
21
21
|
@back_off.reset
|
22
|
-
return
|
22
|
+
return true
|
23
23
|
end
|
24
24
|
|
25
25
|
stop_sse
|
26
26
|
|
27
27
|
schedule_next_token_refresh(@back_off.interval) if response[:retry]
|
28
|
+
false
|
28
29
|
rescue StandardError => e
|
29
30
|
@config.logger.error("start_sse: #{e.inspect}")
|
30
31
|
end
|
@@ -11,8 +11,7 @@ module SplitIoClient
|
|
11
11
|
)
|
12
12
|
@synchronizer = synchronizer
|
13
13
|
notification_manager_keeper = SplitIoClient::SSE::NotificationManagerKeeper.new(config) do |manager|
|
14
|
-
manager.
|
15
|
-
manager.on_push_shutdown { process_push_shutdown }
|
14
|
+
manager.on_action { |action| process_action(action) }
|
16
15
|
end
|
17
16
|
@sse_handler = SplitIoClient::SSE::SSEHandler.new(
|
18
17
|
config,
|
@@ -21,8 +20,7 @@ module SplitIoClient
|
|
21
20
|
repositories[:segments],
|
22
21
|
notification_manager_keeper
|
23
22
|
) do |handler|
|
24
|
-
handler.
|
25
|
-
handler.on_disconnect { |reconnect| process_disconnect(reconnect) }
|
23
|
+
handler.on_action { |action| process_action(action) }
|
26
24
|
end
|
27
25
|
|
28
26
|
@push_manager = PushManager.new(config, @sse_handler, api_key)
|
@@ -44,10 +42,10 @@ module SplitIoClient
|
|
44
42
|
# Starts tasks if stream is enabled.
|
45
43
|
def start_stream
|
46
44
|
@config.logger.debug('Starting push mode ...')
|
47
|
-
|
45
|
+
sync_all_thread
|
48
46
|
@synchronizer.start_periodic_data_recording
|
49
47
|
|
50
|
-
|
48
|
+
start_sse_connection_thread
|
51
49
|
end
|
52
50
|
|
53
51
|
def start_poll
|
@@ -59,23 +57,24 @@ module SplitIoClient
|
|
59
57
|
end
|
60
58
|
|
61
59
|
# Starts thread which fetch splits and segments once and trigger task to periodic data recording.
|
62
|
-
def
|
60
|
+
def sync_all_thread
|
63
61
|
@config.threads[:sync_manager_start_stream] = Thread.new do
|
64
62
|
begin
|
65
63
|
@synchronizer.sync_all
|
66
64
|
rescue StandardError => e
|
67
|
-
@config.logger.error("
|
65
|
+
@config.logger.error("sync_all_thread error : #{e.inspect}")
|
68
66
|
end
|
69
67
|
end
|
70
68
|
end
|
71
69
|
|
72
70
|
# Starts thread which connect to sse and after that fetch splits and segments once.
|
73
|
-
def
|
71
|
+
def start_sse_connection_thread
|
74
72
|
@config.threads[:sync_manager_start_sse] = Thread.new do
|
75
73
|
begin
|
76
|
-
@push_manager.start_sse
|
74
|
+
connected = @push_manager.start_sse
|
75
|
+
@synchronizer.start_periodic_fetch unless connected
|
77
76
|
rescue StandardError => e
|
78
|
-
@config.logger.error("
|
77
|
+
@config.logger.error("start_sse_connection_thread error : #{e.inspect}")
|
79
78
|
end
|
80
79
|
end
|
81
80
|
end
|
@@ -84,6 +83,46 @@ module SplitIoClient
|
|
84
83
|
PhusionPassenger.on_event(:starting_worker_process) { |forked| start_stream if forked }
|
85
84
|
end
|
86
85
|
|
86
|
+
def process_action(action)
|
87
|
+
case action
|
88
|
+
when Constants::PUSH_CONNECTED
|
89
|
+
process_connected
|
90
|
+
when Constants::PUSH_RETRYABLE_ERROR
|
91
|
+
process_disconnect(true)
|
92
|
+
when Constants::PUSH_NONRETRYABLE_ERROR
|
93
|
+
process_disconnect(false)
|
94
|
+
when Constants::PUSH_SUBSYSTEM_DOWN
|
95
|
+
process_subsystem_down
|
96
|
+
when Constants::PUSH_SUBSYSTEM_READY
|
97
|
+
process_subsystem_ready
|
98
|
+
when Constants::PUSH_SUBSYSTEM_OFF
|
99
|
+
process_push_shutdown
|
100
|
+
else
|
101
|
+
@config.logger.debug('Incorrect action type.')
|
102
|
+
end
|
103
|
+
rescue StandardError => e
|
104
|
+
@config.logger.error("process_action error: #{e.inspect}")
|
105
|
+
end
|
106
|
+
|
107
|
+
def process_subsystem_ready
|
108
|
+
@synchronizer.stop_periodic_fetch
|
109
|
+
@synchronizer.sync_all
|
110
|
+
@sse_handler.start_workers
|
111
|
+
end
|
112
|
+
|
113
|
+
def process_subsystem_down
|
114
|
+
@sse_handler.stop_workers
|
115
|
+
@synchronizer.start_periodic_fetch
|
116
|
+
end
|
117
|
+
|
118
|
+
def process_push_shutdown
|
119
|
+
@push_manager.stop_sse
|
120
|
+
@sse_handler.stop_workers
|
121
|
+
@synchronizer.start_periodic_fetch
|
122
|
+
rescue StandardError => e
|
123
|
+
@config.logger.error("process_push_shutdown error: #{e.inspect}")
|
124
|
+
end
|
125
|
+
|
87
126
|
def process_connected
|
88
127
|
if @sse_connected.value
|
89
128
|
@config.logger.debug('Streaming already connected.')
|
@@ -115,28 +154,6 @@ module SplitIoClient
|
|
115
154
|
rescue StandardError => e
|
116
155
|
@config.logger.error("process_disconnect error: #{e.inspect}")
|
117
156
|
end
|
118
|
-
|
119
|
-
def process_occupancy(push_enable)
|
120
|
-
if push_enable
|
121
|
-
@synchronizer.stop_periodic_fetch
|
122
|
-
@synchronizer.sync_all
|
123
|
-
@sse_handler.start_workers
|
124
|
-
return
|
125
|
-
end
|
126
|
-
|
127
|
-
@sse_handler.stop_workers
|
128
|
-
@synchronizer.start_periodic_fetch
|
129
|
-
rescue StandardError => e
|
130
|
-
@config.logger.error("process_occupancy error: #{e.inspect}")
|
131
|
-
end
|
132
|
-
|
133
|
-
def process_push_shutdown
|
134
|
-
@push_manager.stop_sse
|
135
|
-
@sse_handler.stop_workers
|
136
|
-
@synchronizer.start_periodic_fetch
|
137
|
-
rescue StandardError => e
|
138
|
-
@config.logger.error("process_push_shutdown error: #{e.inspect}")
|
139
|
-
end
|
140
157
|
end
|
141
158
|
end
|
142
159
|
end
|
@@ -30,7 +30,7 @@ module SplitIoClient
|
|
30
30
|
def sync_all
|
31
31
|
@config.threads[:sync_all_thread] = Thread.new do
|
32
32
|
@config.logger.debug('Synchronizing Splits and Segments ...') if @config.debug_enabled
|
33
|
-
fetch_splits
|
33
|
+
@split_fetcher.fetch_splits
|
34
34
|
fetch_segments
|
35
35
|
end
|
36
36
|
end
|
@@ -53,21 +53,12 @@ module SplitIoClient
|
|
53
53
|
end
|
54
54
|
|
55
55
|
def fetch_splits
|
56
|
-
|
57
|
-
|
58
|
-
break if @split_fetcher.fetch_splits
|
59
|
-
|
60
|
-
sleep(back_off.interval)
|
61
|
-
end
|
56
|
+
segment_names = @split_fetcher.fetch_splits
|
57
|
+
@segment_fetcher.fetch_segments_if_not_exists(segment_names) unless segment_names.empty?
|
62
58
|
end
|
63
59
|
|
64
60
|
def fetch_segment(name)
|
65
|
-
|
66
|
-
loop do
|
67
|
-
break if @segment_fetcher.fetch_segment(name)
|
68
|
-
|
69
|
-
sleep(back_off.interval)
|
70
|
-
end
|
61
|
+
@segment_fetcher.fetch_segment(name)
|
71
62
|
end
|
72
63
|
|
73
64
|
private
|
@@ -9,6 +9,7 @@ module SplitIoClient
|
|
9
9
|
class Client
|
10
10
|
DEFAULT_READ_TIMEOUT = 70
|
11
11
|
CONNECT_TIMEOUT = 30_000
|
12
|
+
OK_CODE = 200
|
12
13
|
KEEP_ALIVE_RESPONSE = "c\r\n:keepalive\n\n\r\n".freeze
|
13
14
|
ERROR_EVENT_TYPE = 'error'.freeze
|
14
15
|
|
@@ -16,9 +17,10 @@ module SplitIoClient
|
|
16
17
|
@config = config
|
17
18
|
@read_timeout = read_timeout
|
18
19
|
@connected = Concurrent::AtomicBoolean.new(false)
|
20
|
+
@first_event = Concurrent::AtomicBoolean.new(true)
|
19
21
|
@socket = nil
|
20
22
|
@event_parser = SSE::EventSource::EventParser.new(config)
|
21
|
-
@on = { event: ->(_) {},
|
23
|
+
@on = { event: ->(_) {}, action: ->(_) {} }
|
22
24
|
|
23
25
|
yield self if block_given?
|
24
26
|
end
|
@@ -27,16 +29,12 @@ module SplitIoClient
|
|
27
29
|
@on[:event] = action
|
28
30
|
end
|
29
31
|
|
30
|
-
def
|
31
|
-
@on[:
|
32
|
+
def on_action(&action)
|
33
|
+
@on[:action] = action
|
32
34
|
end
|
33
35
|
|
34
|
-
def
|
35
|
-
|
36
|
-
end
|
37
|
-
|
38
|
-
def close(reconnect = false)
|
39
|
-
dispatch_disconnect(reconnect)
|
36
|
+
def close(action = Constants::PUSH_NONRETRYABLE_ERROR)
|
37
|
+
dispatch_action(action)
|
40
38
|
@connected.make_false
|
41
39
|
SplitIoClient::Helpers::ThreadHelper.stop(:connect_stream, @config)
|
42
40
|
@socket&.close
|
@@ -45,6 +43,11 @@ module SplitIoClient
|
|
45
43
|
end
|
46
44
|
|
47
45
|
def start(url)
|
46
|
+
if connected?
|
47
|
+
@config.logger.debug('SSEClient already running.')
|
48
|
+
return true
|
49
|
+
end
|
50
|
+
|
48
51
|
@uri = URI(url)
|
49
52
|
latch = Concurrent::CountDownLatch.new(1)
|
50
53
|
|
@@ -72,16 +75,18 @@ module SplitIoClient
|
|
72
75
|
end
|
73
76
|
|
74
77
|
def connect_stream(latch)
|
75
|
-
socket_write
|
78
|
+
socket_write
|
76
79
|
|
77
|
-
while @
|
80
|
+
while connected? || @first_event.value
|
78
81
|
begin
|
79
82
|
partial_data = @socket.readpartial(10_000, timeout: @read_timeout)
|
80
83
|
|
84
|
+
read_first_event(partial_data, latch)
|
85
|
+
|
81
86
|
raise 'eof exception' if partial_data == :eof
|
82
87
|
rescue StandardError => e
|
83
88
|
@config.logger.error('Error reading partial data: ' + e.inspect) if @config.debug_enabled
|
84
|
-
close(
|
89
|
+
close(Constants::PUSH_RETRYABLE_ERROR)
|
85
90
|
return
|
86
91
|
end
|
87
92
|
|
@@ -89,14 +94,31 @@ module SplitIoClient
|
|
89
94
|
end
|
90
95
|
end
|
91
96
|
|
92
|
-
def socket_write
|
97
|
+
def socket_write
|
98
|
+
@first_event.make_true
|
93
99
|
@socket = socket_connect
|
94
100
|
@socket.write(build_request(@uri))
|
95
|
-
dispatch_connected
|
96
101
|
rescue StandardError => e
|
97
102
|
@config.logger.error("Error during connecting to #{@uri.host}. Error: #{e.inspect}")
|
98
|
-
close
|
99
|
-
|
103
|
+
close(Constants::PUSH_NONRETRYABLE_ERROR)
|
104
|
+
end
|
105
|
+
|
106
|
+
def read_first_event(data, latch)
|
107
|
+
return unless @first_event.value
|
108
|
+
|
109
|
+
response_code = @event_parser.first_event(data)
|
110
|
+
@config.logger.debug("SSE client first event code: #{response_code}")
|
111
|
+
|
112
|
+
error_event = false
|
113
|
+
events = @event_parser.parse(data)
|
114
|
+
events.each { |e| error_event = true if e.event_type == ERROR_EVENT_TYPE }
|
115
|
+
@first_event.make_false
|
116
|
+
|
117
|
+
if response_code == OK_CODE && !error_event
|
118
|
+
@connected.make_true
|
119
|
+
dispatch_action(Constants::PUSH_CONNECTED)
|
120
|
+
end
|
121
|
+
|
100
122
|
latch.count_down
|
101
123
|
end
|
102
124
|
|
@@ -137,9 +159,9 @@ module SplitIoClient
|
|
137
159
|
def dispatch_error(event)
|
138
160
|
@config.logger.error("Event error: #{event.event_type}, #{event.data}")
|
139
161
|
if event.data['code'] >= 40_140 && event.data['code'] <= 40_149
|
140
|
-
close(
|
162
|
+
close(Constants::PUSH_RETRYABLE_ERROR)
|
141
163
|
elsif event.data['code'] >= 40_000 && event.data['code'] <= 49_999
|
142
|
-
close
|
164
|
+
close(Constants::PUSH_NONRETRYABLE_ERROR)
|
143
165
|
end
|
144
166
|
end
|
145
167
|
|
@@ -148,15 +170,9 @@ module SplitIoClient
|
|
148
170
|
@on[:event].call(event)
|
149
171
|
end
|
150
172
|
|
151
|
-
def
|
152
|
-
@
|
153
|
-
@
|
154
|
-
@on[:connected].call
|
155
|
-
end
|
156
|
-
|
157
|
-
def dispatch_disconnect(reconnect)
|
158
|
-
@config.logger.debug('Dispatching disconnect') if @config.debug_enabled
|
159
|
-
@on[:disconnect].call(reconnect)
|
173
|
+
def dispatch_action(action)
|
174
|
+
@config.logger.debug("Dispatching action: #{action}") if @config.debug_enabled
|
175
|
+
@on[:action].call(action)
|
160
176
|
end
|
161
177
|
end
|
162
178
|
end
|
@@ -4,6 +4,8 @@ module SplitIoClient
|
|
4
4
|
module SSE
|
5
5
|
module EventSource
|
6
6
|
class EventParser
|
7
|
+
BAD_REQUEST_CODE = 400
|
8
|
+
|
7
9
|
def initialize(config)
|
8
10
|
@config = config
|
9
11
|
end
|
@@ -27,10 +29,17 @@ module SplitIoClient
|
|
27
29
|
|
28
30
|
events
|
29
31
|
rescue StandardError => e
|
30
|
-
@config.logger.
|
32
|
+
@config.logger.debug("Error during parsing a event: #{e.inspect}")
|
31
33
|
[]
|
32
34
|
end
|
33
35
|
|
36
|
+
def first_event(raw_data)
|
37
|
+
raw_data.split("\n")[0].split(' ')[1].to_i
|
38
|
+
rescue StandardError => e
|
39
|
+
@config.logger.debug("Error parsing first event: #{e.inspect}")
|
40
|
+
BAD_REQUEST_CODE
|
41
|
+
end
|
42
|
+
|
34
43
|
private
|
35
44
|
|
36
45
|
def parse_event_data(data, type)
|
@@ -1,6 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require 'concurrent
|
3
|
+
require 'concurrent'
|
4
4
|
|
5
5
|
module SplitIoClient
|
6
6
|
module SSE
|
@@ -8,7 +8,9 @@ module SplitIoClient
|
|
8
8
|
def initialize(config)
|
9
9
|
@config = config
|
10
10
|
@publisher_available = Concurrent::AtomicBoolean.new(true)
|
11
|
-
@
|
11
|
+
@publishers_pri = Concurrent::AtomicFixnum.new
|
12
|
+
@publishers_sec = Concurrent::AtomicFixnum.new
|
13
|
+
@on = { action: ->(_) {} }
|
12
14
|
|
13
15
|
yield self if block_given?
|
14
16
|
end
|
@@ -16,19 +18,15 @@ module SplitIoClient
|
|
16
18
|
def handle_incoming_occupancy_event(event)
|
17
19
|
if event.data['type'] == 'CONTROL'
|
18
20
|
process_event_control(event.data['controlType'])
|
19
|
-
|
20
|
-
process_event_occupancy(event.data['metrics']['publishers'])
|
21
|
+
else
|
22
|
+
process_event_occupancy(event.channel, event.data['metrics']['publishers'])
|
21
23
|
end
|
22
24
|
rescue StandardError => e
|
23
25
|
@config.logger.error(e)
|
24
26
|
end
|
25
27
|
|
26
|
-
def
|
27
|
-
@on[:
|
28
|
-
end
|
29
|
-
|
30
|
-
def on_push_shutdown(&action)
|
31
|
-
@on[:push_shutdown] = action
|
28
|
+
def on_action(&action)
|
29
|
+
@on[:action] = action
|
32
30
|
end
|
33
31
|
|
34
32
|
private
|
@@ -36,35 +34,42 @@ module SplitIoClient
|
|
36
34
|
def process_event_control(type)
|
37
35
|
case type
|
38
36
|
when 'STREAMING_PAUSED'
|
39
|
-
|
37
|
+
dispatch_action(Constants::PUSH_SUBSYSTEM_DOWN)
|
40
38
|
when 'STREAMING_RESUMED'
|
41
|
-
|
39
|
+
dispatch_action(Constants::PUSH_SUBSYSTEM_READY) if @publisher_available.value
|
42
40
|
when 'STREAMING_DISABLED'
|
43
|
-
|
41
|
+
dispatch_action(Constants::PUSH_SUBSYSTEM_OFF)
|
44
42
|
else
|
45
43
|
@config.logger.error("Incorrect event type: #{incoming_notification}")
|
46
44
|
end
|
47
45
|
end
|
48
46
|
|
49
|
-
def process_event_occupancy(publishers)
|
50
|
-
@config.logger.debug("
|
51
|
-
|
47
|
+
def process_event_occupancy(channel, publishers)
|
48
|
+
@config.logger.debug("Processed occupancy event with #{publishers} publishers. Channel: #{channel}")
|
49
|
+
|
50
|
+
update_publishers(channel, publishers)
|
51
|
+
|
52
|
+
if !are_publishers_available? && @publisher_available.value
|
52
53
|
@publisher_available.make_false
|
53
|
-
|
54
|
-
elsif
|
54
|
+
dispatch_action(Constants::PUSH_SUBSYSTEM_DOWN)
|
55
|
+
elsif are_publishers_available? && !@publisher_available.value
|
55
56
|
@publisher_available.make_true
|
56
|
-
|
57
|
+
dispatch_action(Constants::PUSH_SUBSYSTEM_READY)
|
57
58
|
end
|
58
59
|
end
|
59
60
|
|
60
|
-
def
|
61
|
-
@
|
62
|
-
@
|
61
|
+
def update_publishers(channel, publishers)
|
62
|
+
@publishers_pri.value = publishers if channel == Constants::CONTROL_PRI
|
63
|
+
@publishers_sec.value = publishers if channel == Constants::CONTROL_SEC
|
64
|
+
end
|
65
|
+
|
66
|
+
def are_publishers_available?
|
67
|
+
@publishers_pri.value.positive? || @publishers_sec.value.positive?
|
63
68
|
end
|
64
69
|
|
65
|
-
def
|
66
|
-
@config.logger.debug(
|
67
|
-
@on[:
|
70
|
+
def dispatch_action(action)
|
71
|
+
@config.logger.debug("Dispatching action: #{action}")
|
72
|
+
@on[:action].call(action)
|
68
73
|
end
|
69
74
|
end
|
70
75
|
end
|
@@ -13,11 +13,10 @@ module SplitIoClient
|
|
13
13
|
@notification_processor = SplitIoClient::SSE::NotificationProcessor.new(config, @splits_worker, @segments_worker)
|
14
14
|
@sse_client = SSE::EventSource::Client.new(@config) do |client|
|
15
15
|
client.on_event { |event| handle_incoming_message(event) }
|
16
|
-
client.
|
17
|
-
client.on_disconnect { |reconnect| process_disconnect(reconnect) }
|
16
|
+
client.on_action { |action| process_action(action) }
|
18
17
|
end
|
19
18
|
|
20
|
-
@on = {
|
19
|
+
@on = { action: ->(_) {} }
|
21
20
|
|
22
21
|
yield self if block_given?
|
23
22
|
end
|
@@ -48,22 +47,14 @@ module SplitIoClient
|
|
48
47
|
@segments_worker.stop
|
49
48
|
end
|
50
49
|
|
51
|
-
def
|
52
|
-
@on[:
|
53
|
-
end
|
54
|
-
|
55
|
-
def on_disconnect(&action)
|
56
|
-
@on[:disconnect] = action
|
57
|
-
end
|
58
|
-
|
59
|
-
def process_disconnect(reconnect)
|
60
|
-
@on[:disconnect].call(reconnect)
|
50
|
+
def on_action(&action)
|
51
|
+
@on[:action] = action
|
61
52
|
end
|
62
53
|
|
63
54
|
private
|
64
55
|
|
65
|
-
def
|
66
|
-
@on[:
|
56
|
+
def process_action(action)
|
57
|
+
@on[:action].call(action)
|
67
58
|
end
|
68
59
|
|
69
60
|
def handle_incoming_message(notification)
|
@@ -48,12 +48,13 @@ module SplitIoClient
|
|
48
48
|
def perform
|
49
49
|
while (item = @queue.pop)
|
50
50
|
segment_name = item[:segment_name]
|
51
|
-
|
52
|
-
|
51
|
+
cn = item[:change_number]
|
52
|
+
@config.logger.debug("SegmentsWorker change_number dequeue #{segment_name}, #{cn}")
|
53
53
|
|
54
|
-
|
55
|
-
|
54
|
+
attempt = 0
|
55
|
+
while cn > @segments_repository.get_change_number(segment_name).to_i && attempt <= Workers::MAX_RETRIES_ALLOWED
|
56
56
|
@synchronizer.fetch_segment(segment_name)
|
57
|
+
attempt += 1
|
57
58
|
end
|
58
59
|
end
|
59
60
|
end
|
@@ -3,6 +3,8 @@
|
|
3
3
|
module SplitIoClient
|
4
4
|
module SSE
|
5
5
|
module Workers
|
6
|
+
MAX_RETRIES_ALLOWED = 10
|
7
|
+
|
6
8
|
class SplitsWorker
|
7
9
|
def initialize(synchronizer, config, splits_repository)
|
8
10
|
@synchronizer = synchronizer
|
@@ -59,11 +61,12 @@ module SplitIoClient
|
|
59
61
|
|
60
62
|
def perform
|
61
63
|
while (change_number = @queue.pop)
|
62
|
-
|
64
|
+
@config.logger.debug("SplitsWorker change_number dequeue #{change_number}")
|
63
65
|
|
64
|
-
|
65
|
-
|
66
|
+
attempt = 0
|
67
|
+
while change_number > @splits_repository.get_change_number.to_i && attempt <= Workers::MAX_RETRIES_ALLOWED
|
66
68
|
@synchronizer.fetch_splits
|
69
|
+
attempt += 1
|
67
70
|
end
|
68
71
|
end
|
69
72
|
end
|
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.2.
|
4
|
+
version: 7.2.3.pre.rc2
|
5
5
|
platform: java
|
6
6
|
authors:
|
7
7
|
- Split Software
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2021-02-17 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
requirement: !ruby/object:Gem::Requirement
|
@@ -450,9 +450,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
450
450
|
version: '0'
|
451
451
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
452
452
|
requirements:
|
453
|
-
- - "
|
453
|
+
- - ">"
|
454
454
|
- !ruby/object:Gem::Version
|
455
|
-
version:
|
455
|
+
version: 1.3.1
|
456
456
|
requirements: []
|
457
457
|
rubyforge_project:
|
458
458
|
rubygems_version: 2.6.14
|