ff-ruby-server-sdk 1.4.0 → 1.4.1
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/docs/further_reading.md +5 -3
- data/lib/ff/ruby/server/sdk/api/inner_client_flag_evaluate_callback.rb +1 -1
- data/lib/ff/ruby/server/sdk/api/metrics_event.rb +11 -1
- data/lib/ff/ruby/server/sdk/api/metrics_processor.rb +51 -4
- data/lib/ff/ruby/server/sdk/version.rb +1 -1
- data/scripts/sdk_specs.sh +1 -1
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e2bcc6b6312ee2462bbf6a2a689ddee47c6000bc010db561eb72b5204a7c8d8f
|
4
|
+
data.tar.gz: 7058cd57f6e72cb2c649b51071eaebed405ff3aac691f4aa186a096da70692b9
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 85ff6d9cda7f5579a7eeedce0f7ea293ccf95ff426b413f53aa09c22a0caa4bc1890607c63d67a0b3c58295d537f830a85e81ae45a2a6afafdd4d0521daa60df
|
7
|
+
data.tar.gz: '089aeb5abb536d43e118bade66a80fde7b70e1b74ce1a96fa32d53d7a4a61f08ec7b4c5d35a987e60f11fc4a8791b7233bad01c742bfc4ebc5545a738a13038d'
|
data/docs/further_reading.md
CHANGED
@@ -46,7 +46,7 @@ The synchronous method is useful for environments where feature flag decisions a
|
|
46
46
|
|
47
47
|
You can use the `wait_for_initialization` method, optionally providing a timeout in milliseconds to prevent waiting indefinitely in case of unrecoverable isues, e.g. incorrect API key used.
|
48
48
|
|
49
|
-
**Usage
|
49
|
+
**Usage without a timeout**
|
50
50
|
|
51
51
|
```ruby
|
52
52
|
client = CfClient.instance
|
@@ -57,13 +57,15 @@ client.wait_for_initialization
|
|
57
57
|
result = client.bool_variation("bool_flag", target, false)
|
58
58
|
```
|
59
59
|
|
60
|
-
**Usage
|
60
|
+
**Usage with a timeout**
|
61
61
|
|
62
62
|
```ruby
|
63
63
|
client = CfClient.instance
|
64
64
|
client.init(api_key, config)
|
65
65
|
|
66
|
-
|
66
|
+
# Only wait for 30 seconds, after which if the SDK has not initialized the call will
|
67
|
+
# unblock and the SDK will then serve defaults
|
68
|
+
client.wait_for_initialization(timeout_ms: 30000)
|
67
69
|
|
68
70
|
result = client.bool_variation("bool_flag", target, false)
|
69
71
|
```
|
@@ -23,7 +23,7 @@ class InnerClientFlagEvaluateCallback < FlagEvaluateCallback
|
|
23
23
|
|
24
24
|
def process_evaluation(feature_config, target, variation)
|
25
25
|
|
26
|
-
@logger.debug "Processing evaluation:
|
26
|
+
@logger.debug "Processing evaluation: #{feature_config&.feature || 'nil feature'}, #{target&.identifier || 'nil target'}"
|
27
27
|
|
28
28
|
@metrics_processor.register_evaluation(target, feature_config, variation)
|
29
29
|
end
|
@@ -2,11 +2,12 @@ class MetricsEvent
|
|
2
2
|
|
3
3
|
attr_accessor :feature_config, :target, :variation
|
4
4
|
|
5
|
-
def initialize(feature_config, target, variation)
|
5
|
+
def initialize(feature_config, target, variation, logger)
|
6
6
|
|
7
7
|
@target = target
|
8
8
|
@variation = variation
|
9
9
|
@feature_config = feature_config
|
10
|
+
@logger = logger
|
10
11
|
freeze
|
11
12
|
end
|
12
13
|
|
@@ -15,6 +16,15 @@ class MetricsEvent
|
|
15
16
|
end
|
16
17
|
|
17
18
|
def eql?(other)
|
19
|
+
# Guard clause other is the same type.
|
20
|
+
# While it should be, this adds protection for an edge case we are seeing with very large
|
21
|
+
# project sizes. Issue being tracked in FFM-12192, and once resolved, can feasibly remove
|
22
|
+
# these checks in a future release.
|
23
|
+
unless other.is_a?(MetricsEvent)
|
24
|
+
@logger.warn("Warning: Attempted to compare MetricsEvent with #{other.class.name}" )
|
25
|
+
return false
|
26
|
+
end
|
27
|
+
|
18
28
|
feature_config.feature == other.feature_config.feature and
|
19
29
|
variation.identifier == other.variation.identifier and
|
20
30
|
target.identifier == other.target.identifier
|
@@ -9,6 +9,7 @@ require_relative "../api/metrics_event"
|
|
9
9
|
require_relative "../api/summary_metrics"
|
10
10
|
|
11
11
|
class MetricsProcessor < Closeable
|
12
|
+
GLOBAL_TARGET = Target.new(identifier: "__global__cf_target", name: "Global Target").freeze
|
12
13
|
|
13
14
|
class FrequencyMap < Concurrent::Map
|
14
15
|
def initialize(options = nil, &block)
|
@@ -29,6 +30,7 @@ class MetricsProcessor < Closeable
|
|
29
30
|
self[key]
|
30
31
|
end
|
31
32
|
|
33
|
+
# TODO Will be removed in V2 in favour of simplified clearing. Currently not used outside of tests.
|
32
34
|
def drain_to_map
|
33
35
|
result = {}
|
34
36
|
each_key do |key|
|
@@ -65,7 +67,6 @@ class MetricsProcessor < Closeable
|
|
65
67
|
@target_attribute = "target"
|
66
68
|
@global_target_identifier = "__global__cf_target" # <--- This target identifier is used to aggregate and send data for all
|
67
69
|
# targets as a summary
|
68
|
-
@global_target = Target.new("RubySDK1", identifier = @global_target_identifier, name = @global_target_name)
|
69
70
|
@ready = false
|
70
71
|
@jar_version = Ff::Ruby::Server::Sdk::VERSION
|
71
72
|
@server = "server"
|
@@ -111,12 +112,34 @@ class MetricsProcessor < Closeable
|
|
111
112
|
|
112
113
|
def register_evaluation(target, feature_config, variation)
|
113
114
|
register_evaluation_metric(feature_config, variation)
|
114
|
-
|
115
|
+
if target
|
116
|
+
register_target_metric(target)
|
117
|
+
end
|
115
118
|
end
|
116
119
|
|
117
120
|
private
|
118
121
|
|
119
122
|
def register_evaluation_metric(feature_config, variation)
|
123
|
+
# Guard clause to ensure feature_config, @global_target, and variation are valid.
|
124
|
+
# While they should be, this adds protection for an edge case we are seeing with very large
|
125
|
+
# project sizes. Issue being tracked in FFM-12192, and once resolved, can feasibly remove
|
126
|
+
# these checks in a future release.
|
127
|
+
if feature_config.nil? || !feature_config.respond_to?(:feature) || feature_config.feature.nil?
|
128
|
+
@config.logger.warn("Skipping invalid MetricsEvent: feature_config is missing or incomplete. feature_config=#{feature_config.inspect}")
|
129
|
+
return
|
130
|
+
end
|
131
|
+
|
132
|
+
if GLOBAL_TARGET.nil? || !GLOBAL_TARGET.respond_to?(:identifier) || GLOBAL_TARGET.identifier.nil?
|
133
|
+
@config.logger.warn("Skipping invalid MetricsEvent: global_target is missing or incomplete. global_target=#{GLOBAL_TARGET.inspect}")
|
134
|
+
return
|
135
|
+
end
|
136
|
+
|
137
|
+
if variation.nil? || !variation.respond_to?(:identifier) || variation.identifier.nil?
|
138
|
+
@config.logger.warn("Skipping iInvalid MetricsEvent: variation is missing or incomplete. variation=#{variation.inspect}")
|
139
|
+
return
|
140
|
+
end
|
141
|
+
|
142
|
+
|
120
143
|
if @evaluation_metrics.size > @max_buffer_size
|
121
144
|
unless @evaluation_warning_issued.true?
|
122
145
|
SdkCodes.warn_metrics_evaluations_max_size_exceeded(@config.logger)
|
@@ -125,7 +148,7 @@ class MetricsProcessor < Closeable
|
|
125
148
|
return
|
126
149
|
end
|
127
150
|
|
128
|
-
event = MetricsEvent.new(feature_config,
|
151
|
+
event = MetricsEvent.new(feature_config, GLOBAL_TARGET, variation, @config.logger)
|
129
152
|
@evaluation_metrics.increment event
|
130
153
|
end
|
131
154
|
|
@@ -158,8 +181,14 @@ class MetricsProcessor < Closeable
|
|
158
181
|
end
|
159
182
|
|
160
183
|
def send_data_and_reset_cache(evaluation_metrics_map, target_metrics_map)
|
161
|
-
|
184
|
+
# Clone and clear evaluation metrics map
|
185
|
+
evaluation_metrics_map_clone = Concurrent::Map.new
|
162
186
|
|
187
|
+
evaluation_metrics_map.each_pair do |key, value|
|
188
|
+
evaluation_metrics_map_clone[key] = value
|
189
|
+
end
|
190
|
+
|
191
|
+
evaluation_metrics_map.clear
|
163
192
|
target_metrics_map_clone = Concurrent::Map.new
|
164
193
|
|
165
194
|
target_metrics_map.each_pair do |key, value|
|
@@ -188,6 +217,24 @@ class MetricsProcessor < Closeable
|
|
188
217
|
|
189
218
|
total_count = 0
|
190
219
|
evaluation_metrics_map.each do |key, value|
|
220
|
+
# While Components should not be missing, this adds protection for an edge case we are seeing with very large
|
221
|
+
# project sizes. Issue being tracked in FFM-12192, and once resolved, can feasibly remove
|
222
|
+
# these checks in a future release.
|
223
|
+
# Initialize an array to collect missing components
|
224
|
+
missing_components = []
|
225
|
+
|
226
|
+
# Check each required component and add to missing_components if absent
|
227
|
+
missing_components << 'feature_config' unless key.respond_to?(:feature_config) && key.feature_config
|
228
|
+
missing_components << 'variation' unless key.respond_to?(:variation) && key.variation
|
229
|
+
missing_components << 'target' unless key.respond_to?(:target) && key.target
|
230
|
+
missing_components << 'count' if value.nil?
|
231
|
+
|
232
|
+
# If any components are missing, log a detailed warning and skip processing
|
233
|
+
unless missing_components.empty?
|
234
|
+
@config.logger.warn "Skipping invalid metrics event: missing #{missing_components.join(', ')} in key: #{key.inspect}, full details: #{key.inspect}"
|
235
|
+
next
|
236
|
+
end
|
237
|
+
|
191
238
|
total_count += value
|
192
239
|
metrics_data = OpenapiClient::MetricsData.new({ :attributes => [] })
|
193
240
|
metrics_data.timestamp = (Time.now.to_f * 1000).to_i
|
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.1
|
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
|
+
date: 2024-11-12 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rake
|
@@ -305,7 +305,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
305
305
|
- !ruby/object:Gem::Version
|
306
306
|
version: '0'
|
307
307
|
requirements: []
|
308
|
-
rubygems_version: 3.5.
|
308
|
+
rubygems_version: 3.5.22
|
309
309
|
signing_key:
|
310
310
|
specification_version: 4
|
311
311
|
summary: Harness is a feature management platform that helps teams to build better
|