splitclient-rb 8.10.1 → 8.11.0.pre.rc1
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/lib/splitclient-rb/cache/repositories/rule_based_segments_repository.rb +14 -1
- data/lib/splitclient-rb/cache/repositories/segments_repository.rb +11 -1
- data/lib/splitclient-rb/cache/repositories/splits_repository.rb +23 -1
- data/lib/splitclient-rb/clients/split_client.rb +10 -1
- data/lib/splitclient-rb/engine/api/faraday_middleware/gzip.rb +1 -0
- data/lib/splitclient-rb/engine/events/events_delivery.rb +20 -0
- data/lib/splitclient-rb/engine/events/events_manager.rb +188 -0
- data/lib/splitclient-rb/engine/events/events_manager_config.rb +96 -0
- data/lib/splitclient-rb/engine/events/events_task.rb +50 -0
- data/lib/splitclient-rb/engine/events/noop_events_queue.rb +13 -0
- data/lib/splitclient-rb/engine/models/event_active_subscriptions.rb +14 -0
- data/lib/splitclient-rb/engine/models/events_metadata.rb +10 -0
- data/lib/splitclient-rb/engine/models/sdk_event.rb +4 -0
- data/lib/splitclient-rb/engine/models/sdk_event_type.rb +4 -0
- data/lib/splitclient-rb/engine/models/sdk_internal_event.rb +8 -0
- data/lib/splitclient-rb/engine/models/sdk_internal_event_notification.rb +14 -0
- data/lib/splitclient-rb/engine/models/valid_sdk_event.rb +14 -0
- data/lib/splitclient-rb/engine/status_manager.rb +7 -1
- data/lib/splitclient-rb/split_factory.rb +20 -5
- data/lib/splitclient-rb/version.rb +1 -1
- data/lib/splitclient-rb.rb +12 -0
- metadata +13 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 29c8e0a3cff07d455060b5eca7b419ab2dc0edb83b1740949e4f8e5db986b336
|
|
4
|
+
data.tar.gz: 01071de244cee1ab454ece8c72633001d8c575dc9421caad257a1f35bbab6677
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: b7c9a15a9d245f43a7477ef34da2f2b41150cff32bb2d342935091e62ca44fa2aa69162832f95adab4bcaba5caa245aad81695f0eb1444a5c5b29ca70e58261e
|
|
7
|
+
data.tar.gz: 480ff3da51ab9daae21ef20d55b124cbba2e0d2c92e971708cdb5bbfd5be42a83e3a4e6a3ae9da97f41ce8779231fbaf2e630b05b90c0fc4e230594caf933b3d
|
|
@@ -28,7 +28,7 @@ module SplitIoClient
|
|
|
28
28
|
RB_SEGMENTS_PREFIX = '.rbsegment.'
|
|
29
29
|
REGISTERED_PREFIX = '.segments.registered'
|
|
30
30
|
|
|
31
|
-
def initialize(config)
|
|
31
|
+
def initialize(config, internal_events_queue)
|
|
32
32
|
super(config)
|
|
33
33
|
@adapter = case @config.cache_adapter.class.to_s
|
|
34
34
|
when 'SplitIoClient::Cache::Adapters::RedisAdapter'
|
|
@@ -40,12 +40,25 @@ module SplitIoClient
|
|
|
40
40
|
@adapter.set_string(namespace_key(TILL_PREFIX), '-1')
|
|
41
41
|
@adapter.initialize_map(namespace_key(REGISTERED_PREFIX))
|
|
42
42
|
end
|
|
43
|
+
@internal_events_queue = internal_events_queue
|
|
43
44
|
end
|
|
44
45
|
|
|
45
46
|
def update(to_add, to_delete, new_change_number)
|
|
46
47
|
to_add.each{ |rule_based_segment| add_rule_based_segment(rule_based_segment) }
|
|
47
48
|
to_delete.each{ |rule_based_segment| remove_rule_based_segment(rule_based_segment) }
|
|
48
49
|
set_change_number(new_change_number)
|
|
50
|
+
|
|
51
|
+
if to_add.length > 0 || to_delete.length > 0
|
|
52
|
+
@internal_events_queue.push(
|
|
53
|
+
SplitIoClient::Engine::Models::SdkInternalEventNotification.new(
|
|
54
|
+
SplitIoClient::Engine::Models::SdkInternalEvent::RB_SEGMENTS_UPDATED,
|
|
55
|
+
SplitIoClient::Engine::Models::EventsMetadata.new(
|
|
56
|
+
SplitIoClient::Engine::Models::SdkEventType::SEGMENTS_UPDATE,
|
|
57
|
+
[]
|
|
58
|
+
)
|
|
59
|
+
)
|
|
60
|
+
)
|
|
61
|
+
end
|
|
49
62
|
end
|
|
50
63
|
|
|
51
64
|
def get_rule_based_segment(name)
|
|
@@ -6,7 +6,7 @@ module SplitIoClient
|
|
|
6
6
|
|
|
7
7
|
attr_reader :adapter
|
|
8
8
|
|
|
9
|
-
def initialize(config)
|
|
9
|
+
def initialize(config, internal_events_queue)
|
|
10
10
|
super(config)
|
|
11
11
|
@adapter = case @config.cache_adapter.class.to_s
|
|
12
12
|
when 'SplitIoClient::Cache::Adapters::RedisAdapter'
|
|
@@ -15,6 +15,7 @@ module SplitIoClient
|
|
|
15
15
|
@config.cache_adapter
|
|
16
16
|
end
|
|
17
17
|
@adapter.set_bool(namespace_key('.ready'), false) unless @config.mode.equal?(:consumer)
|
|
18
|
+
@internal_events_queue = internal_events_queue
|
|
18
19
|
end
|
|
19
20
|
|
|
20
21
|
# Receives segment data, adds and removes segements from the store
|
|
@@ -25,6 +26,15 @@ module SplitIoClient
|
|
|
25
26
|
|
|
26
27
|
add_keys(name, segment[:added])
|
|
27
28
|
remove_keys(name, segment[:removed])
|
|
29
|
+
@internal_events_queue.push(
|
|
30
|
+
SplitIoClient::Engine::Models::SdkInternalEventNotification.new(
|
|
31
|
+
SplitIoClient::Engine::Models::SdkInternalEvent::SEGMENTS_UPDATED,
|
|
32
|
+
SplitIoClient::Engine::Models::EventsMetadata.new(
|
|
33
|
+
SplitIoClient::Engine::Models::SdkEventType::SEGMENTS_UPDATE,
|
|
34
|
+
[]
|
|
35
|
+
)
|
|
36
|
+
)
|
|
37
|
+
)
|
|
28
38
|
end
|
|
29
39
|
|
|
30
40
|
def get_segment_keys(name)
|
|
@@ -35,7 +35,7 @@ module SplitIoClient
|
|
|
35
35
|
SPLIT_PREFIX = '.split.'
|
|
36
36
|
READY_PREFIX = '.splits.ready'
|
|
37
37
|
|
|
38
|
-
def initialize(config, flag_sets_repository, flag_set_filter)
|
|
38
|
+
def initialize(config, flag_sets_repository, flag_set_filter, internal_events_queue)
|
|
39
39
|
super(config)
|
|
40
40
|
@tt_cache = {}
|
|
41
41
|
@adapter = case @config.cache_adapter.class.to_s
|
|
@@ -46,6 +46,7 @@ module SplitIoClient
|
|
|
46
46
|
end
|
|
47
47
|
@flag_sets = flag_sets_repository
|
|
48
48
|
@flag_set_filter = flag_set_filter
|
|
49
|
+
@internal_events_queue = internal_events_queue
|
|
49
50
|
initialize_keys
|
|
50
51
|
end
|
|
51
52
|
|
|
@@ -53,6 +54,18 @@ module SplitIoClient
|
|
|
53
54
|
to_add.each{ |feature_flag| add_feature_flag(feature_flag) }
|
|
54
55
|
to_delete.each{ |feature_flag| remove_feature_flag(feature_flag) }
|
|
55
56
|
set_change_number(new_change_number)
|
|
57
|
+
|
|
58
|
+
if to_add.length > 0 || to_delete.length > 0
|
|
59
|
+
@internal_events_queue.push(
|
|
60
|
+
SplitIoClient::Engine::Models::SdkInternalEventNotification.new(
|
|
61
|
+
SplitIoClient::Engine::Models::SdkInternalEvent::FLAGS_UPDATED,
|
|
62
|
+
SplitIoClient::Engine::Models::EventsMetadata.new(
|
|
63
|
+
SplitIoClient::Engine::Models::SdkEventType::FLAG_UPDATE,
|
|
64
|
+
to_add.map {|flag| flag[:name]} | to_delete.map {|flag| flag[:name]}
|
|
65
|
+
)
|
|
66
|
+
)
|
|
67
|
+
)
|
|
68
|
+
end
|
|
56
69
|
end
|
|
57
70
|
|
|
58
71
|
def get_split(name)
|
|
@@ -140,6 +153,15 @@ module SplitIoClient
|
|
|
140
153
|
split[:changeNumber] = change_number
|
|
141
154
|
|
|
142
155
|
@adapter.set_string(namespace_key(".split.#{split_name}"), split.to_json)
|
|
156
|
+
@internal_events_queue.push(
|
|
157
|
+
SplitIoClient::Engine::Models::SdkInternalEventNotification.new(
|
|
158
|
+
SplitIoClient::Engine::Models::SdkInternalEvent::FLAG_KILLED_NOTIFICATION,
|
|
159
|
+
SplitIoClient::Engine::Models::EventsMetadata.new(
|
|
160
|
+
SplitIoClient::Engine::Models::SdkEventType::FLAG_UPDATE,
|
|
161
|
+
[split_name]
|
|
162
|
+
)
|
|
163
|
+
)
|
|
164
|
+
)
|
|
143
165
|
end
|
|
144
166
|
|
|
145
167
|
def splits_count
|
|
@@ -18,7 +18,7 @@ module SplitIoClient
|
|
|
18
18
|
# @param sdk_key [String] the SDK key for your split account
|
|
19
19
|
#
|
|
20
20
|
# @return [SplitIoClient] split.io client instance
|
|
21
|
-
def initialize(sdk_key, repositories, status_manager, config, impressions_manager, telemetry_evaluation_producer, evaluator, split_validator, fallback_treatment_calculator)
|
|
21
|
+
def initialize(sdk_key, repositories, status_manager, config, impressions_manager, telemetry_evaluation_producer, evaluator, split_validator, fallback_treatment_calculator, events_manager)
|
|
22
22
|
@api_key = sdk_key
|
|
23
23
|
@splits_repository = repositories[:splits]
|
|
24
24
|
@segments_repository = repositories[:segments]
|
|
@@ -33,6 +33,7 @@ module SplitIoClient
|
|
|
33
33
|
@split_validator = split_validator
|
|
34
34
|
@evaluator = evaluator
|
|
35
35
|
@fallback_treatment_calculator = fallback_treatment_calculator
|
|
36
|
+
@events_manager = events_manager
|
|
36
37
|
end
|
|
37
38
|
|
|
38
39
|
def get_treatment(
|
|
@@ -176,6 +177,14 @@ module SplitIoClient
|
|
|
176
177
|
@status_manager.wait_until_ready(time) if @status_manager
|
|
177
178
|
end
|
|
178
179
|
|
|
180
|
+
def register(sdk_event, handler)
|
|
181
|
+
@events_manager.register(sdk_event, handler)
|
|
182
|
+
end
|
|
183
|
+
|
|
184
|
+
def unregister(sdk_event, handler)
|
|
185
|
+
@events_manager.unregister(sdk_event)
|
|
186
|
+
end
|
|
187
|
+
|
|
179
188
|
private
|
|
180
189
|
|
|
181
190
|
def check_properties_size(properties_size, msg = "Event not queued")
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module SplitIoClient
|
|
4
|
+
module Engine
|
|
5
|
+
module Events
|
|
6
|
+
class EventsDelivery
|
|
7
|
+
def initialize(config)
|
|
8
|
+
@config = config
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def deliver(sdk_event, event_metadata, event_handler)
|
|
12
|
+
event_handler.call(event_metadata)
|
|
13
|
+
rescue StandardError => e
|
|
14
|
+
@config.logger.error("Exception when calling handler for Sdk Event #{sdk_event}")
|
|
15
|
+
@config.log_found_exception(__method__.to_s, e)
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module SplitIoClient
|
|
4
|
+
module Engine
|
|
5
|
+
module Events
|
|
6
|
+
class EventsManager
|
|
7
|
+
def initialize(events_manager_config, events_delivery, config)
|
|
8
|
+
@manager_config = events_manager_config
|
|
9
|
+
@events_delivery = events_delivery
|
|
10
|
+
@active_subscriptions = {}
|
|
11
|
+
@internal_events_status = {}
|
|
12
|
+
@mutex = Mutex.new
|
|
13
|
+
@config = config
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def register(sdk_event, event_handler)
|
|
17
|
+
return if @active_subscriptions.key?(sdk_event) && !get_event_handler(sdk_event).nil?
|
|
18
|
+
|
|
19
|
+
@mutex.synchronize do
|
|
20
|
+
# SDK ready already fired
|
|
21
|
+
if sdk_event == SplitIoClient::Engine::Models::SdkEvent::SDK_READY && event_already_triggered(sdk_event)
|
|
22
|
+
@active_subscriptions[sdk_event] = SplitIoClient::Engine::Models::EventActiveSubscriptions.new(true, event_handler)
|
|
23
|
+
@config.logger.debug('EventsManager: Firing SDK_READY event for new subscription') if @config.debug_enabled
|
|
24
|
+
fire_sdk_event(sdk_event, nil)
|
|
25
|
+
return
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
@config.logger.debug("EventsManager: Register event: #{sdk_event}") if @config.debug_enabled
|
|
29
|
+
@active_subscriptions[sdk_event] = SplitIoClient::Engine::Models::EventActiveSubscriptions.new(false, event_handler)
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def unregister(sdk_event)
|
|
34
|
+
return unless @active_subscriptions.key?(sdk_event)
|
|
35
|
+
|
|
36
|
+
@mutex.synchronize do
|
|
37
|
+
@active_subscriptions.delete(sdk_event)
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def notify_internal_event(sdk_internal_event, event_metadata)
|
|
42
|
+
@mutex.synchronize do
|
|
43
|
+
update_internal_event_status(sdk_internal_event, true)
|
|
44
|
+
@manager_config.evaluation_order.each do |sorted_event|
|
|
45
|
+
if get_sdk_event_if_applicable(sdk_internal_event).include?(sorted_event) &&
|
|
46
|
+
!get_event_handler(sorted_event).nil?
|
|
47
|
+
fire_sdk_event(sorted_event, event_metadata)
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
# if client is not subscribed to SDK_READY
|
|
51
|
+
if sorted_event == SplitIoClient::Engine::Models::SdkEvent::SDK_READY && get_event_handler(sorted_event).nil?
|
|
52
|
+
@config.logger.debug('EventsManager: Registering SDK_READY event as fired') if @config.debug_enabled
|
|
53
|
+
@active_subscriptions[Engine::Models::SdkEvent::SDK_READY] = Engine::Models::EventActiveSubscriptions.new(true, nil)
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def destroy
|
|
60
|
+
@mutex.synchronize do
|
|
61
|
+
@active_subscriptions = {}
|
|
62
|
+
@internal_events_status = {}
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
private
|
|
67
|
+
|
|
68
|
+
def fire_sdk_event(sdk_event, event_metadata)
|
|
69
|
+
@config.logger.debug("EventsManager: Firing Sdk event: #{sdk_event}") if @config.debug_enabled
|
|
70
|
+
@config.threads[:sdk_event_notify] = Thread.new do
|
|
71
|
+
@events_delivery.deliver(sdk_event, event_metadata, get_event_handler(sdk_event))
|
|
72
|
+
end
|
|
73
|
+
sdk_event_triggered(sdk_event)
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
def event_already_triggered(sdk_event)
|
|
77
|
+
return @active_subscriptions[sdk_event].triggered if @active_subscriptions.key?(sdk_event)
|
|
78
|
+
|
|
79
|
+
false
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
def get_internal_event_status(sdk_internal_event)
|
|
83
|
+
return @internal_events_status[sdk_internal_event] if @internal_events_status.key?(sdk_internal_event)
|
|
84
|
+
|
|
85
|
+
false
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
def update_internal_event_status(sdk_internal_event, status)
|
|
89
|
+
@internal_events_status[sdk_internal_event] = status
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
def sdk_event_triggered(sdk_event)
|
|
93
|
+
return unless @active_subscriptions.key?(sdk_event)
|
|
94
|
+
|
|
95
|
+
return if @active_subscriptions[sdk_event].triggered
|
|
96
|
+
|
|
97
|
+
@active_subscriptions[sdk_event].triggered = true
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
def get_event_handler(sdk_event)
|
|
101
|
+
return nil unless @active_subscriptions.key?(sdk_event)
|
|
102
|
+
|
|
103
|
+
@active_subscriptions[sdk_event].handler
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
def get_sdk_event_if_applicable(sdk_internal_event)
|
|
107
|
+
final_sdk_event = SplitIoClient::Engine::Models::ValidSdkEvent.new(nil, false)
|
|
108
|
+
|
|
109
|
+
events_to_fire = []
|
|
110
|
+
require_any_sdk_event = check_require_any(sdk_internal_event)
|
|
111
|
+
if require_any_sdk_event.valid
|
|
112
|
+
if (!event_already_triggered(require_any_sdk_event.sdk_event) &&
|
|
113
|
+
execution_limit(require_any_sdk_event.sdk_event) == 1) ||
|
|
114
|
+
execution_limit(require_any_sdk_event.sdk_event) == -1
|
|
115
|
+
final_sdk_event = SplitIoClient::Engine::Models::ValidSdkEvent.new(
|
|
116
|
+
require_any_sdk_event.sdk_event,
|
|
117
|
+
check_prerequisites(require_any_sdk_event.sdk_event) &&
|
|
118
|
+
check_suppressed_by(require_any_sdk_event.sdk_event)
|
|
119
|
+
)
|
|
120
|
+
end
|
|
121
|
+
events_to_fire.push(final_sdk_event.sdk_event) if final_sdk_event.valid
|
|
122
|
+
end
|
|
123
|
+
check_require_all.each { |sdk_event| events_to_fire.push(sdk_event) }
|
|
124
|
+
|
|
125
|
+
events_to_fire
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
def check_require_all
|
|
129
|
+
events = []
|
|
130
|
+
@manager_config.require_all.each do |require_name, require_value|
|
|
131
|
+
final_status = true
|
|
132
|
+
require_value.each { |val| final_status &= get_internal_event_status(val) }
|
|
133
|
+
events.push(require_name) if check_event_eligible_conditions(final_status, require_name, require_value)
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
events
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
def check_event_eligible_conditions(final_status, require_name, require_value)
|
|
140
|
+
final_status &&
|
|
141
|
+
check_prerequisites(require_name) &&
|
|
142
|
+
((!event_already_triggered(require_name) &&
|
|
143
|
+
execution_limit(require_name) == 1) ||
|
|
144
|
+
execution_limit(require_name) == -1) &&
|
|
145
|
+
require_value.length.positive?
|
|
146
|
+
end
|
|
147
|
+
|
|
148
|
+
def check_prerequisites(sdk_event)
|
|
149
|
+
@manager_config.prerequisites.each do |name, value|
|
|
150
|
+
value.each do |val|
|
|
151
|
+
return false if name == sdk_event && !event_already_triggered(val)
|
|
152
|
+
end
|
|
153
|
+
end
|
|
154
|
+
|
|
155
|
+
true
|
|
156
|
+
end
|
|
157
|
+
|
|
158
|
+
def check_suppressed_by(sdk_event)
|
|
159
|
+
@manager_config.suppressed_by.each do |name, value|
|
|
160
|
+
value.each do |val|
|
|
161
|
+
return false if name == sdk_event && event_already_triggered(val)
|
|
162
|
+
end
|
|
163
|
+
end
|
|
164
|
+
|
|
165
|
+
true
|
|
166
|
+
end
|
|
167
|
+
|
|
168
|
+
def execution_limit(sdk_event)
|
|
169
|
+
return -1 unless @manager_config.execution_limits.key?(sdk_event)
|
|
170
|
+
|
|
171
|
+
@manager_config.execution_limits[sdk_event]
|
|
172
|
+
end
|
|
173
|
+
|
|
174
|
+
def check_require_any(sdk_internal_event)
|
|
175
|
+
valid_sdk_event = SplitIoClient::Engine::Models::ValidSdkEvent.new(nil, false)
|
|
176
|
+
@manager_config.require_any.each do |name, val|
|
|
177
|
+
if val.include?(sdk_internal_event)
|
|
178
|
+
valid_sdk_event = SplitIoClient::Engine::Models::ValidSdkEvent.new(name, true)
|
|
179
|
+
return valid_sdk_event
|
|
180
|
+
end
|
|
181
|
+
end
|
|
182
|
+
|
|
183
|
+
valid_sdk_event
|
|
184
|
+
end
|
|
185
|
+
end
|
|
186
|
+
end
|
|
187
|
+
end
|
|
188
|
+
end
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module SplitIoClient
|
|
4
|
+
module Engine
|
|
5
|
+
module Events
|
|
6
|
+
class EventsManagerConfig
|
|
7
|
+
attr_accessor :require_all, :prerequisites, :require_any, :suppressed_by, :execution_limits, :evaluation_order
|
|
8
|
+
|
|
9
|
+
def initialize
|
|
10
|
+
@require_all = construct_require_all
|
|
11
|
+
@prerequisites = construct_prerequisites
|
|
12
|
+
@require_any = construct_require_any
|
|
13
|
+
@suppressed_by = construct_suppressed_by
|
|
14
|
+
@execution_limits = construct_execution_limits
|
|
15
|
+
@evaluation_order = construct_sorted_events
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
private
|
|
19
|
+
|
|
20
|
+
def construct_require_all
|
|
21
|
+
{
|
|
22
|
+
SplitIoClient::Engine::Models::SdkEvent::SDK_READY => Set.new([SplitIoClient::Engine::Models::SdkInternalEvent::SDK_READY])
|
|
23
|
+
}
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def construct_prerequisites
|
|
27
|
+
{
|
|
28
|
+
SplitIoClient::Engine::Models::SdkEvent::SDK_UPDATE => Set.new([SplitIoClient::Engine::Models::SdkEvent::SDK_READY])
|
|
29
|
+
}
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def construct_require_any
|
|
33
|
+
{
|
|
34
|
+
SplitIoClient::Engine::Models::SdkEvent::SDK_UPDATE => Set.new(
|
|
35
|
+
[
|
|
36
|
+
SplitIoClient::Engine::Models::SdkInternalEvent::FLAG_KILLED_NOTIFICATION,
|
|
37
|
+
SplitIoClient::Engine::Models::SdkInternalEvent::FLAGS_UPDATED,
|
|
38
|
+
SplitIoClient::Engine::Models::SdkInternalEvent::RB_SEGMENTS_UPDATED,
|
|
39
|
+
SplitIoClient::Engine::Models::SdkInternalEvent::SEGMENTS_UPDATED
|
|
40
|
+
]
|
|
41
|
+
)
|
|
42
|
+
}
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def construct_suppressed_by
|
|
46
|
+
{}
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def construct_execution_limits
|
|
50
|
+
{
|
|
51
|
+
SplitIoClient::Engine::Models::SdkEvent::SDK_READY => 1,
|
|
52
|
+
SplitIoClient::Engine::Models::SdkEvent::SDK_UPDATE => -1
|
|
53
|
+
}
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def construct_sorted_events
|
|
57
|
+
sorted_events = []
|
|
58
|
+
[SplitIoClient::Engine::Models::SdkEvent::SDK_READY, SplitIoClient::Engine::Models::SdkEvent::SDK_UPDATE].each do |sdk_event|
|
|
59
|
+
sorted_events = dfs_recursive(sdk_event, sorted_events)
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
sorted_events
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def dfs_recursive(sdk_event, added)
|
|
66
|
+
return added if added.include?(sdk_event)
|
|
67
|
+
|
|
68
|
+
get_dependencies(sdk_event).each do |dependent_event|
|
|
69
|
+
added = dfs_recursive(dependent_event, added)
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
added.push(sdk_event)
|
|
73
|
+
|
|
74
|
+
added
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
def get_dependencies(sdk_event)
|
|
78
|
+
dependencies = Set.new
|
|
79
|
+
@prerequisites.each do |prerequisites_event_name, prerequisites_event_value|
|
|
80
|
+
next unless prerequisites_event_name == sdk_event
|
|
81
|
+
|
|
82
|
+
prerequisites_event_value.each do |prereq_event|
|
|
83
|
+
dependencies.add(prereq_event)
|
|
84
|
+
end
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
@suppressed_by.each do |suppressed_event_name, suppressed_event_value|
|
|
88
|
+
dependencies.add(suppressed_event_name) if suppressed_event_value.include?(sdk_event)
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
dependencies
|
|
92
|
+
end
|
|
93
|
+
end
|
|
94
|
+
end
|
|
95
|
+
end
|
|
96
|
+
end
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module SplitIoClient
|
|
4
|
+
module Engine
|
|
5
|
+
module Events
|
|
6
|
+
class EventsTask
|
|
7
|
+
attr_accessor :running
|
|
8
|
+
|
|
9
|
+
def initialize(notify_internal_events, internal_events_queue, config)
|
|
10
|
+
@notify_internal_events = notify_internal_events
|
|
11
|
+
@internal_events_queue = internal_events_queue
|
|
12
|
+
@config = config
|
|
13
|
+
@running = false
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def start
|
|
17
|
+
return if @running
|
|
18
|
+
|
|
19
|
+
@config.logger.info('Starting Internal Events Task.')
|
|
20
|
+
@running = true
|
|
21
|
+
@config.threads[:internal_events_task] = Thread.new do
|
|
22
|
+
worker_thread
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def stop
|
|
27
|
+
return unless @running
|
|
28
|
+
|
|
29
|
+
@config.logger.info('Stopping Internal Events Task.')
|
|
30
|
+
@running = false
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
private
|
|
34
|
+
|
|
35
|
+
def worker_thread
|
|
36
|
+
while (event = @internal_events_queue.pop)
|
|
37
|
+
break unless @running
|
|
38
|
+
|
|
39
|
+
@config.logger.debug("Processing sdk internal event: #{event.internal_event}") if @config.debug_enabled
|
|
40
|
+
begin
|
|
41
|
+
@notify_internal_events.call(event.internal_event, event.metadata)
|
|
42
|
+
rescue StandardError => e
|
|
43
|
+
@config.log_found_exception(__method__.to_s, e)
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# frozen_string_literal: false
|
|
2
|
+
|
|
3
|
+
module SplitIoClient
|
|
4
|
+
module Engine::Models
|
|
5
|
+
class EventActiveSubscriptions
|
|
6
|
+
attr_accessor :triggered, :handler
|
|
7
|
+
|
|
8
|
+
def initialize(triggered, handler)
|
|
9
|
+
@triggered = triggered
|
|
10
|
+
@handler = handler
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
class SplitIoClient::Engine::Models::SdkInternalEvent
|
|
2
|
+
SDK_READY = 'SDK_READY'
|
|
3
|
+
FLAGS_UPDATED = 'FLAGS_UPDATED'
|
|
4
|
+
FLAG_KILLED_NOTIFICATION = 'FLAG_KILLED_NOTIFICATION'
|
|
5
|
+
SEGMENTS_UPDATED = 'SEGMENTS_UPDATED'
|
|
6
|
+
RB_SEGMENTS_UPDATED = 'RB_SEGMENTS_UPDATED'
|
|
7
|
+
LARGE_SEGMENTS_UPDATED = 'LARGE_SEGMENTS_UPDATED'
|
|
8
|
+
end
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# frozen_string_literal: false
|
|
2
|
+
|
|
3
|
+
module SplitIoClient
|
|
4
|
+
module Engine::Models
|
|
5
|
+
class SdkInternalEventNotification
|
|
6
|
+
attr_reader :internal_event, :metadata
|
|
7
|
+
|
|
8
|
+
def initialize(internal_event, metadata)
|
|
9
|
+
@internal_event = internal_event
|
|
10
|
+
@metadata = metadata
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
|
@@ -3,9 +3,10 @@
|
|
|
3
3
|
module SplitIoClient
|
|
4
4
|
module Engine
|
|
5
5
|
class StatusManager
|
|
6
|
-
def initialize(config)
|
|
6
|
+
def initialize(config, internal_events_queue)
|
|
7
7
|
@config = config
|
|
8
8
|
@sdk_ready = Concurrent::CountDownLatch.new(1)
|
|
9
|
+
@internal_events_queue = internal_events_queue
|
|
9
10
|
end
|
|
10
11
|
|
|
11
12
|
def ready?
|
|
@@ -19,6 +20,11 @@ module SplitIoClient
|
|
|
19
20
|
|
|
20
21
|
@sdk_ready.count_down
|
|
21
22
|
@config.logger.info('SplitIO SDK is ready')
|
|
23
|
+
@internal_events_queue.push(
|
|
24
|
+
SplitIoClient::Engine::Models::SdkInternalEventNotification.new(
|
|
25
|
+
SplitIoClient::Engine::Models::SdkInternalEvent::SDK_READY, nil
|
|
26
|
+
)
|
|
27
|
+
)
|
|
22
28
|
end
|
|
23
29
|
|
|
24
30
|
def wait_until_ready(seconds = nil)
|
|
@@ -45,6 +45,7 @@ module SplitIoClient
|
|
|
45
45
|
|
|
46
46
|
register_factory
|
|
47
47
|
|
|
48
|
+
build_events_manager
|
|
48
49
|
build_telemetry_components
|
|
49
50
|
build_flag_sets_filter
|
|
50
51
|
build_repositories
|
|
@@ -53,13 +54,13 @@ module SplitIoClient
|
|
|
53
54
|
build_unique_keys_tracker
|
|
54
55
|
build_impressions_components
|
|
55
56
|
|
|
56
|
-
@status_manager = Engine::StatusManager.new(@config)
|
|
57
|
+
@status_manager = Engine::StatusManager.new(@config, @internal_events_queue)
|
|
57
58
|
@split_validator = SplitIoClient::Validators.new(@config)
|
|
58
59
|
@evaluator = Engine::Parser::Evaluator.new(@segments_repository, @splits_repository, @rule_based_segment_repository, @config)
|
|
59
60
|
|
|
60
61
|
start!
|
|
61
62
|
fallback_treatment_calculator = SplitIoClient::Engine::FallbackTreatmentCalculator.new(@config.fallback_treatments_configuration)
|
|
62
|
-
@client = SplitClient.new(@api_key, repositories, @status_manager, @config, @impressions_manager, @evaluation_producer, @evaluator, @split_validator, fallback_treatment_calculator)
|
|
63
|
+
@client = SplitClient.new(@api_key, repositories, @status_manager, @config, @impressions_manager, @evaluation_producer, @evaluator, @split_validator, fallback_treatment_calculator, @events_manager)
|
|
63
64
|
@manager = SplitManager.new(@splits_repository, @status_manager, @config)
|
|
64
65
|
end
|
|
65
66
|
|
|
@@ -219,9 +220,9 @@ module SplitIoClient
|
|
|
219
220
|
else
|
|
220
221
|
@flag_sets_repository = SplitIoClient::Cache::Repositories::MemoryFlagSetsRepository.new(@config.flag_sets_filter)
|
|
221
222
|
end
|
|
222
|
-
@splits_repository = SplitsRepository.new(@config, @flag_sets_repository, @flag_sets_filter)
|
|
223
|
-
@segments_repository = SegmentsRepository.new(@config)
|
|
224
|
-
@rule_based_segment_repository = RuleBasedSegmentsRepository.new(@config)
|
|
223
|
+
@splits_repository = SplitsRepository.new(@config, @flag_sets_repository, @flag_sets_filter, @internal_events_queue)
|
|
224
|
+
@segments_repository = SegmentsRepository.new(@config, @internal_events_queue)
|
|
225
|
+
@rule_based_segment_repository = RuleBasedSegmentsRepository.new(@config, @internal_events_queue)
|
|
225
226
|
@impressions_repository = ImpressionsRepository.new(@config)
|
|
226
227
|
@events_repository = EventsRepository.new(@config, @api_key, @runtime_producer)
|
|
227
228
|
end
|
|
@@ -265,5 +266,19 @@ module SplitIoClient
|
|
|
265
266
|
def build_flag_sets_filter
|
|
266
267
|
@flag_sets_filter = SplitIoClient::Cache::Filter::FlagSetsFilter.new(@config.flag_sets_filter)
|
|
267
268
|
end
|
|
269
|
+
|
|
270
|
+
def build_events_manager
|
|
271
|
+
@events_manager = Engine::Events::EventsManager.new(Engine::Events::EventsManagerConfig.new,
|
|
272
|
+
Engine::Events::EventsDelivery.new(@config),
|
|
273
|
+
@config)
|
|
274
|
+
if @config.consumer?
|
|
275
|
+
@internal_events_queue = Engine::Events::NoOpEventsQueue.new
|
|
276
|
+
return
|
|
277
|
+
end
|
|
278
|
+
|
|
279
|
+
@internal_events_queue = Queue.new
|
|
280
|
+
@events_task = Engine::Events::EventsTask.new(@events_manager.method(:notify_internal_event), @internal_events_queue, @config)
|
|
281
|
+
@events_task.start
|
|
282
|
+
end
|
|
268
283
|
end
|
|
269
284
|
end
|
data/lib/splitclient-rb.rb
CHANGED
|
@@ -66,6 +66,11 @@ require 'splitclient-rb/engine/api/telemetry_api'
|
|
|
66
66
|
require 'splitclient-rb/engine/common/impressions_counter'
|
|
67
67
|
require 'splitclient-rb/engine/common/impressions_manager'
|
|
68
68
|
require 'splitclient-rb/engine/common/noop_impressions_counter'
|
|
69
|
+
require 'splitclient-rb/engine/events/events_manager_config.rb'
|
|
70
|
+
require 'splitclient-rb/engine/events/events_manager.rb'
|
|
71
|
+
require 'splitclient-rb/engine/events/events_task.rb'
|
|
72
|
+
require 'splitclient-rb/engine/events/events_delivery.rb'
|
|
73
|
+
require 'splitclient-rb/engine/events/noop_events_queue.rb'
|
|
69
74
|
require 'splitclient-rb/engine/parser/condition'
|
|
70
75
|
require 'splitclient-rb/engine/parser/partition'
|
|
71
76
|
require 'splitclient-rb/engine/parser/evaluator'
|
|
@@ -112,6 +117,13 @@ require 'splitclient-rb/engine/models/split_http_response'
|
|
|
112
117
|
require 'splitclient-rb/engine/models/evaluation_options'
|
|
113
118
|
require 'splitclient-rb/engine/models/fallback_treatment.rb'
|
|
114
119
|
require 'splitclient-rb/engine/models/fallback_treatments_configuration.rb'
|
|
120
|
+
require 'splitclient-rb/engine/models/events_metadata.rb'
|
|
121
|
+
require 'splitclient-rb/engine/models/sdk_event_type.rb'
|
|
122
|
+
require 'splitclient-rb/engine/models/sdk_event.rb'
|
|
123
|
+
require 'splitclient-rb/engine/models/sdk_internal_event.rb'
|
|
124
|
+
require 'splitclient-rb/engine/models/sdk_internal_event_notification.rb'
|
|
125
|
+
require 'splitclient-rb/engine/models/valid_sdk_event.rb'
|
|
126
|
+
require 'splitclient-rb/engine/models/event_active_subscriptions.rb'
|
|
115
127
|
require 'splitclient-rb/engine/auth_api_client'
|
|
116
128
|
require 'splitclient-rb/engine/back_off'
|
|
117
129
|
require 'splitclient-rb/engine/fallback_treatment_calculator.rb'
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: splitclient-rb
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 8.
|
|
4
|
+
version: 8.11.0.pre.rc1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Split Software
|
|
@@ -460,6 +460,11 @@ files:
|
|
|
460
460
|
- lib/splitclient-rb/engine/common/impressions_manager.rb
|
|
461
461
|
- lib/splitclient-rb/engine/common/noop_impressions_counter.rb
|
|
462
462
|
- lib/splitclient-rb/engine/evaluator/splitter.rb
|
|
463
|
+
- lib/splitclient-rb/engine/events/events_delivery.rb
|
|
464
|
+
- lib/splitclient-rb/engine/events/events_manager.rb
|
|
465
|
+
- lib/splitclient-rb/engine/events/events_manager_config.rb
|
|
466
|
+
- lib/splitclient-rb/engine/events/events_task.rb
|
|
467
|
+
- lib/splitclient-rb/engine/events/noop_events_queue.rb
|
|
463
468
|
- lib/splitclient-rb/engine/fallback_treatment_calculator.rb
|
|
464
469
|
- lib/splitclient-rb/engine/impressions/noop_unique_keys_tracker.rb
|
|
465
470
|
- lib/splitclient-rb/engine/impressions/unique_keys_tracker.rb
|
|
@@ -495,13 +500,20 @@ files:
|
|
|
495
500
|
- lib/splitclient-rb/engine/matchers/whitelist_matcher.rb
|
|
496
501
|
- lib/splitclient-rb/engine/metrics/binary_search_latency_tracker.rb
|
|
497
502
|
- lib/splitclient-rb/engine/models/evaluation_options.rb
|
|
503
|
+
- lib/splitclient-rb/engine/models/event_active_subscriptions.rb
|
|
504
|
+
- lib/splitclient-rb/engine/models/events_metadata.rb
|
|
498
505
|
- lib/splitclient-rb/engine/models/fallback_treatment.rb
|
|
499
506
|
- lib/splitclient-rb/engine/models/fallback_treatments_configuration.rb
|
|
500
507
|
- lib/splitclient-rb/engine/models/label.rb
|
|
508
|
+
- lib/splitclient-rb/engine/models/sdk_event.rb
|
|
509
|
+
- lib/splitclient-rb/engine/models/sdk_event_type.rb
|
|
510
|
+
- lib/splitclient-rb/engine/models/sdk_internal_event.rb
|
|
511
|
+
- lib/splitclient-rb/engine/models/sdk_internal_event_notification.rb
|
|
501
512
|
- lib/splitclient-rb/engine/models/segment_type.rb
|
|
502
513
|
- lib/splitclient-rb/engine/models/split.rb
|
|
503
514
|
- lib/splitclient-rb/engine/models/split_http_response.rb
|
|
504
515
|
- lib/splitclient-rb/engine/models/treatment.rb
|
|
516
|
+
- lib/splitclient-rb/engine/models/valid_sdk_event.rb
|
|
505
517
|
- lib/splitclient-rb/engine/parser/condition.rb
|
|
506
518
|
- lib/splitclient-rb/engine/parser/evaluator.rb
|
|
507
519
|
- lib/splitclient-rb/engine/parser/partition.rb
|