ff-ruby-server-sdk 1.4.1 → 1.4.3
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
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 21ede6e2de94f3ed2aec871c40b8dbee7a9feec6adbdec14726e5237caedbb0b
|
4
|
+
data.tar.gz: e89c0b57ae84666c87dccf6b25a67f0d0ca77990220ee014c9abe1a1225993c9
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 943c5b49c1bf887dd6ff24edce3e03cd2bff1badde8dd0802fdc8bda042e2e260b2cd7929c18189ec9dfb39f8b8189bec5b49e32ab021c722a17da71268bcccb
|
7
|
+
data.tar.gz: 5f32b626e8c49fd3074401db1ef6810acfb79b4cdba6f03e7f55e31a2a6e921b73ce273d71780f30dc90f18e74f691e4a203da6503bb0a473a60e49b0b56d37b
|
@@ -1,56 +1,23 @@
|
|
1
|
-
|
1
|
+
require 'singleton'
|
2
2
|
require_relative "../../generated/lib/openapi_client"
|
3
3
|
require_relative "../common/closeable"
|
4
4
|
require_relative "inner_client"
|
5
5
|
|
6
6
|
class CfClient < Closeable
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
@@instance
|
7
|
+
include Singleton
|
8
|
+
|
9
|
+
def init(api_key, config, connector = nil)
|
10
|
+
# Only initialize if @client is nil to avoid reinitialization
|
11
|
+
unless @client
|
12
|
+
@config = config || ConfigBuilder.new.build
|
13
|
+
@client = InnerClient.new(api_key, @config, connector)
|
14
|
+
@config.logger.debug "Client initialized with API key: #{api_key}"
|
16
15
|
end
|
16
|
+
@client
|
17
17
|
end
|
18
18
|
|
19
|
-
# Static - End
|
20
|
-
|
21
|
-
def initialize(api_key = nil, config = nil, connector = nil)
|
22
|
-
|
23
|
-
if config == nil
|
24
|
-
|
25
|
-
@config = ConfigBuilder.new.build
|
26
|
-
else
|
27
|
-
|
28
|
-
@config = config
|
29
|
-
end
|
30
|
-
|
31
|
-
@client = InnerClient.new(api_key, config, connector)
|
32
|
-
|
33
|
-
@config.logger.debug "Client (1): " + @client.to_s
|
34
|
-
end
|
35
|
-
|
36
|
-
def init(api_key = nil, config = nil, connector = nil)
|
37
|
-
|
38
|
-
if @client == nil
|
39
|
-
|
40
|
-
@config = config
|
41
|
-
|
42
|
-
@client = InnerClient.new(
|
43
|
-
|
44
|
-
api_key = api_key,
|
45
|
-
config = config,
|
46
|
-
connector = connector
|
47
|
-
)
|
48
|
-
|
49
|
-
@config.logger.debug "Client (2): " + @client.to_s
|
50
|
-
end
|
51
|
-
end
|
52
19
|
|
53
|
-
|
20
|
+
def wait_for_initialization(timeout_ms: nil)
|
54
21
|
if @client != nil
|
55
22
|
@client.wait_for_initialization(timeout: timeout_ms)
|
56
23
|
end
|
@@ -78,28 +78,25 @@ class MetricsProcessor < Closeable
|
|
78
78
|
|
79
79
|
@executor = Concurrent::FixedThreadPool.new(10)
|
80
80
|
|
81
|
+
# Used for locking the evalution and target metrics maps before we clone them
|
82
|
+
@metric_maps_mutex = Mutex.new
|
81
83
|
@evaluation_metrics = FrequencyMap.new
|
82
84
|
@target_metrics = Concurrent::Map.new
|
83
85
|
|
84
86
|
# Keep track of targets that have already been sent to avoid sending them again
|
85
87
|
@seen_targets = Concurrent::Map.new
|
86
88
|
|
87
|
-
@max_buffer_size = config.buffer_size - 1
|
88
|
-
|
89
|
-
# Max 100k targets per interval
|
90
|
-
@max_targets_buffer_size = 100000
|
91
|
-
|
92
|
-
@evaluation_warning_issued = Concurrent::AtomicBoolean.new
|
93
|
-
@target_warning_issued = Concurrent::AtomicBoolean.new
|
94
|
-
|
95
89
|
@callback.on_metrics_ready
|
96
90
|
end
|
97
91
|
|
98
92
|
def start
|
99
|
-
@config.logger.debug "Starting metrics processor with request interval:
|
100
|
-
|
93
|
+
@config.logger.debug "Starting metrics processor with request interval: #{@config.frequency}"
|
94
|
+
if @running
|
95
|
+
@config.logger.warn "Metrics processor is already running."
|
96
|
+
else
|
97
|
+
start_async
|
98
|
+
end
|
101
99
|
end
|
102
|
-
|
103
100
|
def stop
|
104
101
|
@config.logger.debug "Stopping metrics processor"
|
105
102
|
stop_async
|
@@ -139,28 +136,13 @@ class MetricsProcessor < Closeable
|
|
139
136
|
return
|
140
137
|
end
|
141
138
|
|
142
|
-
|
143
|
-
if @evaluation_metrics.size > @max_buffer_size
|
144
|
-
unless @evaluation_warning_issued.true?
|
145
|
-
SdkCodes.warn_metrics_evaluations_max_size_exceeded(@config.logger)
|
146
|
-
@evaluation_warning_issued.make_true
|
147
|
-
end
|
148
|
-
return
|
149
|
-
end
|
150
|
-
|
151
139
|
event = MetricsEvent.new(feature_config, GLOBAL_TARGET, variation, @config.logger)
|
152
|
-
@
|
140
|
+
@metric_maps_mutex.synchronize do
|
141
|
+
@evaluation_metrics.increment event
|
142
|
+
end
|
153
143
|
end
|
154
144
|
|
155
145
|
def register_target_metric(target)
|
156
|
-
if @target_metrics.size > @max_targets_buffer_size
|
157
|
-
unless @target_warning_issued.true?
|
158
|
-
SdkCodes.warn_metrics_targets_max_size_exceeded(@config.logger)
|
159
|
-
@target_warning_issued.make_true
|
160
|
-
end
|
161
|
-
return
|
162
|
-
end
|
163
|
-
|
164
146
|
if target.is_private
|
165
147
|
return
|
166
148
|
end
|
@@ -171,34 +153,39 @@ class MetricsProcessor < Closeable
|
|
171
153
|
return
|
172
154
|
end
|
173
155
|
|
174
|
-
@
|
156
|
+
@metric_maps_mutex.synchronize do
|
157
|
+
@target_metrics.put(target.identifier, target)
|
158
|
+
end
|
175
159
|
end
|
176
160
|
|
177
161
|
def run_one_iteration
|
178
162
|
send_data_and_reset_cache(@evaluation_metrics, @target_metrics)
|
179
|
-
|
180
|
-
@config.logger.debug "metrics: frequency map size #{@evaluation_metrics.size}. targets map size #{@target_metrics.size} global target size #{@seen_targets.size}"
|
181
163
|
end
|
182
164
|
|
183
165
|
def send_data_and_reset_cache(evaluation_metrics_map, target_metrics_map)
|
184
|
-
#
|
185
|
-
|
166
|
+
# A single lock is used to synchronise access to both the evaluation and target metrics maps.
|
167
|
+
# While separate locks could be applied to each map individually, we want an interval's eval/target
|
168
|
+
# metrics to be processed in an atomic unit.
|
169
|
+
evaluation_metrics_map_clone, target_metrics_map_clone = @metric_maps_mutex.synchronize do
|
170
|
+
|
171
|
+
clone_evaluations = Concurrent::Map.new
|
172
|
+
clone_targets = Concurrent::Map.new
|
173
|
+
# Clone and clear evaluation metrics map
|
174
|
+
evaluation_metrics_map.each_pair do |key, value|
|
175
|
+
clone_evaluations[key] = value
|
176
|
+
end
|
186
177
|
|
187
|
-
|
188
|
-
evaluation_metrics_map_clone[key] = value
|
189
|
-
end
|
178
|
+
evaluation_metrics_map.clear
|
190
179
|
|
191
|
-
|
192
|
-
|
180
|
+
target_metrics_map.each_pair do |key, value|
|
181
|
+
clone_targets[key] = value
|
182
|
+
end
|
193
183
|
|
194
|
-
|
195
|
-
target_metrics_map_clone[key] = value
|
196
|
-
end
|
184
|
+
target_metrics_map.clear
|
197
185
|
|
198
|
-
|
186
|
+
[clone_evaluations, clone_targets]
|
199
187
|
|
200
|
-
|
201
|
-
@target_warning_issued.make_false
|
188
|
+
end
|
202
189
|
|
203
190
|
metrics = prepare_summary_metrics_body(evaluation_metrics_map_clone, target_metrics_map_clone)
|
204
191
|
|
@@ -286,6 +273,7 @@ class MetricsProcessor < Closeable
|
|
286
273
|
def start_async
|
287
274
|
@config.logger.debug "Async starting: " + self.to_s
|
288
275
|
@ready = true
|
276
|
+
@running = true
|
289
277
|
@thread = Thread.new do
|
290
278
|
@config.logger.debug "Async started: " + self.to_s
|
291
279
|
while @ready do
|
@@ -303,8 +291,14 @@ class MetricsProcessor < Closeable
|
|
303
291
|
def stop_async
|
304
292
|
@ready = false
|
305
293
|
@initialized = false
|
294
|
+
if @thread && @thread.alive?
|
295
|
+
@thread.join
|
296
|
+
@config.logger.debug "Metrics processor thread has been stopped."
|
297
|
+
end
|
298
|
+
@running = false
|
306
299
|
end
|
307
300
|
|
301
|
+
|
308
302
|
def get_version
|
309
303
|
Ff::Ruby::Server::Sdk::VERSION
|
310
304
|
end
|
data/scripts/sdk_specs.sh
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ff-ruby-server-sdk
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.4.
|
4
|
+
version: 1.4.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- 'Miloš Vasić, cyr.: Милош Васић'
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-11-
|
11
|
+
date: 2024-11-13 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rake
|