splitclient-rb 8.11.0 → 8.11.1.pre.beta1
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/CHANGES.txt +5 -0
- data/LICENSE +1 -1
- data/lib/splitclient-rb/cache/repositories/segments_repository.rb +0 -1
- data/lib/splitclient-rb/engine/auth_api_client.rb +6 -2
- data/lib/splitclient-rb/engine/events/events_manager.rb +8 -8
- data/lib/splitclient-rb/engine/matchers/rule_based_segment_matcher.rb +1 -1
- data/lib/splitclient-rb/engine/models/sdk_internal_event_notification.rb +8 -6
- data/lib/splitclient-rb/engine/sync_manager.rb +13 -10
- data/lib/splitclient-rb/sse/event_source/client.rb +1 -1
- data/lib/splitclient-rb/sse/workers/splits_worker.rb +6 -2
- data/lib/splitclient-rb/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 4a4db5832f1014e1affbb3d8dc9449fb5b90b5a85f711d2adc1b23c68930f0d1
|
|
4
|
+
data.tar.gz: fcaaf6956533c33c1208db241b7abd3e926b733721088688e57b7b7902f13427
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: d1a06b2e4e9fc50d0c29e0b1a5a4b8525d89ce1e98212bb771a2237326ccfe5de5d2612a5dff9203efbdff3bae053289bc7c16a51a8200629f4bba11e392892f
|
|
7
|
+
data.tar.gz: 6bd725d5b1ff5e882f27f4d86dcdb4966e0d93f188e1f30a3031a6c291cd82b63fd72a7458f36d6d3b231878282a7ab485f0dc1cbda60c55b4f8d6ea566f0b5d
|
data/CHANGES.txt
CHANGED
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
CHANGES
|
|
2
2
|
|
|
3
|
+
8.11.0 (Mar, 12, 2026)
|
|
4
|
+
- Added the ability to listen to different events triggered by the SDK. Read more in our docs.
|
|
5
|
+
- SDK_UPDATE notify when a flag or user segment has changed
|
|
6
|
+
- SDK_READY notify when the SDK is ready to evaluate
|
|
7
|
+
|
|
3
8
|
8.10.1 (Jan 28, 2025)
|
|
4
9
|
- Fixed rule-based segment matcher to exit when a conition is met.
|
|
5
10
|
- Fixed impressions properties format in redis mode.
|
data/LICENSE
CHANGED
|
@@ -157,7 +157,7 @@ Apache License
|
|
|
157
157
|
file or class name and description of purpose be included on the
|
|
158
158
|
same "printed page" as the copyright notice for easier
|
|
159
159
|
identification within third-party archives.
|
|
160
|
-
Copyright
|
|
160
|
+
Copyright 2025 Harness Corporation
|
|
161
161
|
Licensed under the Apache License, Version 2.0 (the "License");
|
|
162
162
|
you may not use this file except in compliance with the License.
|
|
163
163
|
You may obtain a copy of the License at
|
|
@@ -23,7 +23,6 @@ module SplitIoClient
|
|
|
23
23
|
name = segment[:name]
|
|
24
24
|
|
|
25
25
|
@adapter.initialize_set(segment_data(name)) unless @adapter.exists?(segment_data(name))
|
|
26
|
-
@config.logger.debug(segment)
|
|
27
26
|
add_keys(name, segment[:added])
|
|
28
27
|
remove_keys(name, segment[:removed])
|
|
29
28
|
if segment[:added].length > 0 || segment[:removed].length > 0
|
|
@@ -21,7 +21,9 @@ module SplitIoClient
|
|
|
21
21
|
return process_error(response) if response.status >= 400 && response.status < 500
|
|
22
22
|
|
|
23
23
|
@telemetry_runtime_producer.record_sync_error(Telemetry::Domain::Constants::TOKEN_SYNC, response.status.to_i)
|
|
24
|
-
|
|
24
|
+
if @config.debug_enabled
|
|
25
|
+
@config.logger.debug("Error connecting to: #{@config.auth_service_url}. Response status: #{response.status}")
|
|
26
|
+
end
|
|
25
27
|
{ push_enabled: false, retry: true }
|
|
26
28
|
rescue StandardError => e
|
|
27
29
|
@config.logger.debug("AuthApiClient error: #{e.inspect}.") if @config.debug_enabled
|
|
@@ -51,7 +53,9 @@ module SplitIoClient
|
|
|
51
53
|
end
|
|
52
54
|
|
|
53
55
|
def process_error(response)
|
|
54
|
-
|
|
56
|
+
if @config.debug_enabled
|
|
57
|
+
@config.logger.debug("Error connecting to: #{@config.auth_service_url}. Response status: #{response.status}")
|
|
58
|
+
end
|
|
55
59
|
@telemetry_runtime_producer.record_auth_rejections if response.status == 401
|
|
56
60
|
|
|
57
61
|
{ push_enabled: false, retry: false }
|
|
@@ -18,15 +18,15 @@ module SplitIoClient
|
|
|
18
18
|
|
|
19
19
|
@mutex.synchronize do
|
|
20
20
|
# SDK ready already fired
|
|
21
|
-
if sdk_event ==
|
|
22
|
-
@active_subscriptions[sdk_event] =
|
|
21
|
+
if sdk_event == Engine::Models::SdkEvent::SDK_READY && event_already_triggered(sdk_event)
|
|
22
|
+
@active_subscriptions[sdk_event] = Engine::Models::EventActiveSubscriptions.new(true, event_handler)
|
|
23
23
|
@config.logger.debug('EventsManager: Firing SDK_READY event for new subscription') if @config.debug_enabled
|
|
24
24
|
fire_sdk_event(sdk_event, nil)
|
|
25
25
|
return
|
|
26
26
|
end
|
|
27
27
|
|
|
28
28
|
@config.logger.debug("EventsManager: Register event: #{sdk_event}") if @config.debug_enabled
|
|
29
|
-
@active_subscriptions[sdk_event] =
|
|
29
|
+
@active_subscriptions[sdk_event] = Engine::Models::EventActiveSubscriptions.new(false, event_handler)
|
|
30
30
|
end
|
|
31
31
|
end
|
|
32
32
|
|
|
@@ -66,7 +66,7 @@ module SplitIoClient
|
|
|
66
66
|
private
|
|
67
67
|
|
|
68
68
|
def check_if_register_needed(sorted_event)
|
|
69
|
-
sorted_event ==
|
|
69
|
+
sorted_event == Engine::Models::SdkEvent::SDK_READY &&
|
|
70
70
|
get_event_handler(sorted_event).nil? &&
|
|
71
71
|
!@active_subscriptions.include?(sorted_event)
|
|
72
72
|
end
|
|
@@ -110,7 +110,7 @@ module SplitIoClient
|
|
|
110
110
|
end
|
|
111
111
|
|
|
112
112
|
def get_sdk_event_if_applicable(sdk_internal_event)
|
|
113
|
-
final_sdk_event =
|
|
113
|
+
final_sdk_event = Engine::Models::ValidSdkEvent.new(nil, false)
|
|
114
114
|
|
|
115
115
|
events_to_fire = []
|
|
116
116
|
require_any_sdk_event = check_require_any(sdk_internal_event)
|
|
@@ -118,7 +118,7 @@ module SplitIoClient
|
|
|
118
118
|
if (!event_already_triggered(require_any_sdk_event.sdk_event) &&
|
|
119
119
|
execution_limit(require_any_sdk_event.sdk_event) == 1) ||
|
|
120
120
|
execution_limit(require_any_sdk_event.sdk_event) == -1
|
|
121
|
-
final_sdk_event =
|
|
121
|
+
final_sdk_event = Engine::Models::ValidSdkEvent.new(
|
|
122
122
|
require_any_sdk_event.sdk_event,
|
|
123
123
|
check_prerequisites(require_any_sdk_event.sdk_event) &&
|
|
124
124
|
check_suppressed_by(require_any_sdk_event.sdk_event)
|
|
@@ -178,10 +178,10 @@ module SplitIoClient
|
|
|
178
178
|
end
|
|
179
179
|
|
|
180
180
|
def check_require_any(sdk_internal_event)
|
|
181
|
-
valid_sdk_event =
|
|
181
|
+
valid_sdk_event = Engine::Models::ValidSdkEvent.new(nil, false)
|
|
182
182
|
@manager_config.require_any.each do |name, val|
|
|
183
183
|
if val.include?(sdk_internal_event)
|
|
184
|
-
valid_sdk_event =
|
|
184
|
+
valid_sdk_event = Engine::Models::ValidSdkEvent.new(name, true)
|
|
185
185
|
return valid_sdk_event
|
|
186
186
|
end
|
|
187
187
|
end
|
|
@@ -40,7 +40,7 @@ module SplitIoClient
|
|
|
40
40
|
break if matched
|
|
41
41
|
end
|
|
42
42
|
|
|
43
|
-
@logger.debug("[InRuleSegmentMatcher] #{@segment_name} is in rule based segment -> #{matched}")
|
|
43
|
+
@config.logger.debug("[InRuleSegmentMatcher] #{@segment_name} is in rule based segment -> #{matched}") if @config.debug_enabled
|
|
44
44
|
matched
|
|
45
45
|
end
|
|
46
46
|
|
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
# frozen_string_literal: false
|
|
2
2
|
|
|
3
3
|
module SplitIoClient
|
|
4
|
-
module Engine
|
|
5
|
-
|
|
6
|
-
|
|
4
|
+
module Engine
|
|
5
|
+
module Models
|
|
6
|
+
class SdkInternalEventNotification
|
|
7
|
+
attr_reader :internal_event, :metadata
|
|
7
8
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
9
|
+
def initialize(internal_event, metadata)
|
|
10
|
+
@internal_event = internal_event
|
|
11
|
+
@metadata = metadata
|
|
12
|
+
end
|
|
11
13
|
end
|
|
12
14
|
end
|
|
13
15
|
end
|
|
@@ -6,14 +6,8 @@ module SplitIoClient
|
|
|
6
6
|
SYNC_MODE_STREAMING = 0
|
|
7
7
|
SYNC_MODE_POLLING = 1
|
|
8
8
|
|
|
9
|
-
def initialize(config,
|
|
10
|
-
|
|
11
|
-
telemetry_runtime_producer,
|
|
12
|
-
telemetry_synchronizer,
|
|
13
|
-
status_manager,
|
|
14
|
-
sse_handler,
|
|
15
|
-
push_manager,
|
|
16
|
-
status_queue)
|
|
9
|
+
def initialize(config, synchronizer, telemetry_runtime_producer, telemetry_synchronizer,
|
|
10
|
+
status_manager, sse_handler, push_manager, status_queue)
|
|
17
11
|
@config = config
|
|
18
12
|
@synchronizer = synchronizer
|
|
19
13
|
@telemetry_runtime_producer = telemetry_runtime_producer
|
|
@@ -23,6 +17,7 @@ module SplitIoClient
|
|
|
23
17
|
@push_manager = push_manager
|
|
24
18
|
@status_queue = status_queue
|
|
25
19
|
@sse_connected = Concurrent::AtomicBoolean.new(false)
|
|
20
|
+
@back_off = Engine::BackOff.new(1, 3)
|
|
26
21
|
end
|
|
27
22
|
|
|
28
23
|
def start
|
|
@@ -119,7 +114,7 @@ module SplitIoClient
|
|
|
119
114
|
end
|
|
120
115
|
|
|
121
116
|
def process_disconnect(reconnect)
|
|
122
|
-
unless @sse_connected.value
|
|
117
|
+
unless @sse_connected.value || reconnect
|
|
123
118
|
@config.logger.debug('Streaming already disconnected.') if @config.debug_enabled
|
|
124
119
|
return
|
|
125
120
|
end
|
|
@@ -130,6 +125,9 @@ module SplitIoClient
|
|
|
130
125
|
record_telemetry(Telemetry::Domain::Constants::SYNC_MODE, SYNC_MODE_POLLING)
|
|
131
126
|
|
|
132
127
|
if reconnect
|
|
128
|
+
wait_interval = @back_off.interval
|
|
129
|
+
@config.logger.debug("Retrying streaming connection in: #{wait_interval} seconds")
|
|
130
|
+
sleep(wait_interval)
|
|
133
131
|
@push_manager.stop_sse
|
|
134
132
|
@synchronizer.sync_all
|
|
135
133
|
@push_manager.start_sse
|
|
@@ -155,6 +153,7 @@ module SplitIoClient
|
|
|
155
153
|
|
|
156
154
|
case status
|
|
157
155
|
when Constants::PUSH_CONNECTED
|
|
156
|
+
@back_off.reset
|
|
158
157
|
process_connected
|
|
159
158
|
when Constants::PUSH_RETRYABLE_ERROR
|
|
160
159
|
process_disconnect(true)
|
|
@@ -169,12 +168,16 @@ module SplitIoClient
|
|
|
169
168
|
when Constants::PUSH_SUBSYSTEM_OFF
|
|
170
169
|
process_push_shutdown
|
|
171
170
|
else
|
|
172
|
-
|
|
171
|
+
log_if_debug('Incorrect push status type.')
|
|
173
172
|
end
|
|
174
173
|
end
|
|
175
174
|
rescue StandardError => e
|
|
176
175
|
@config.logger.error("Push status handler error: #{e.inspect}")
|
|
177
176
|
end
|
|
178
177
|
end
|
|
178
|
+
|
|
179
|
+
def log_if_debug(msg)
|
|
180
|
+
@config.logger.debug(msg) if @config.debug_enabled
|
|
181
|
+
end
|
|
179
182
|
end
|
|
180
183
|
end
|
|
@@ -86,7 +86,7 @@ module SplitIoClient
|
|
|
86
86
|
end
|
|
87
87
|
|
|
88
88
|
def connect_stream(latch)
|
|
89
|
-
return Constants::
|
|
89
|
+
return Constants::PUSH_RETRYABLE_ERROR unless socket_write(latch)
|
|
90
90
|
while connected? || @first_event.value
|
|
91
91
|
begin
|
|
92
92
|
if IO.select([@socket], nil, nil, @read_timeout)
|
|
@@ -52,7 +52,9 @@ module SplitIoClient
|
|
|
52
52
|
|
|
53
53
|
def perform
|
|
54
54
|
while (notification = @queue.pop)
|
|
55
|
-
|
|
55
|
+
if @config.debug_enabled
|
|
56
|
+
@config.logger.debug("feature_flags_worker change_number dequeue #{notification.data['changeNumber']}")
|
|
57
|
+
end
|
|
56
58
|
case notification.data['type']
|
|
57
59
|
when SSE::EventSource::EventTypes::SPLIT_UPDATE
|
|
58
60
|
success = update_feature_flag(notification)
|
|
@@ -117,7 +119,9 @@ module SplitIoClient
|
|
|
117
119
|
def kill_feature_flag(notification)
|
|
118
120
|
return if @feature_flags_repository.get_change_number.to_i > notification.data['changeNumber']
|
|
119
121
|
|
|
120
|
-
|
|
122
|
+
if @config.debug_enabled
|
|
123
|
+
@config.logger.debug("feature_flags_worker kill #{notification.data['splitName']}, #{notification.data['changeNumber']}")
|
|
124
|
+
end
|
|
121
125
|
@feature_flags_repository.kill(notification.data['changeNumber'],
|
|
122
126
|
notification.data['splitName'],
|
|
123
127
|
notification.data['defaultTreatment'])
|