ff-ruby-server-sdk 1.4.4 → 1.4.5
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/ff/ruby/server/sdk/api/evaluator.rb +3 -1
- data/lib/ff/ruby/server/sdk/api/inner_client_flag_evaluate_callback.rb +3 -3
- data/lib/ff/ruby/server/sdk/api/metrics_processor.rb +23 -34
- data/lib/ff/ruby/server/sdk/version.rb +1 -1
- data/lib/ff/ruby/server/sdk.rb +0 -1
- data/scripts/sdk_specs.sh +1 -1
- metadata +2 -3
- data/lib/ff/ruby/server/sdk/api/metrics_event.rb +0 -53
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a4ab2e35a2f4c9b26b92808b6bd3c8bc1b91dd7be7449fa1ed42324dc7a5dd8c
|
4
|
+
data.tar.gz: d426cc3eadd246b1db5fa67ec583fb4f5c38591195579b780687ad5582262e5e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 970504a5a04c27c883b12efc6a54cec3486c14789c3a49389a33dad1d8f43fa0f6fb26046628f397368c4cfa9eb1bd6eca91fb28b72062cd7cec8f0c69ca487a
|
7
|
+
data.tar.gz: d4fc7208a07a8fec31990f693358b649c5b8e63f23f9b95c605b3321d6d45e9d7a5934b262fcd248c06d3322de450eb3a3686bac63ebc8bf426e18fba2f32cf5
|
@@ -117,7 +117,9 @@ class Evaluator < Evaluation
|
|
117
117
|
|
118
118
|
if variation != nil
|
119
119
|
if callback != nil
|
120
|
-
|
120
|
+
feature_name = flag.feature
|
121
|
+
variation_identifier = variation.identifier
|
122
|
+
callback.process_evaluation(feature_name, target, variation_identifier)
|
121
123
|
end
|
122
124
|
return variation
|
123
125
|
end
|
@@ -21,10 +21,10 @@ class InnerClientFlagEvaluateCallback < FlagEvaluateCallback
|
|
21
21
|
@metrics_processor = metrics_processor
|
22
22
|
end
|
23
23
|
|
24
|
-
def process_evaluation(
|
24
|
+
def process_evaluation(feature_name, target, variation_identifier)
|
25
25
|
|
26
|
-
@logger.debug "Processing evaluation: #{
|
26
|
+
@logger.debug "Processing evaluation: #{feature_name || 'nil feature'}, #{variation_identifier || 'nil variation'}, #{target&.identifier || 'nil target'}"
|
27
27
|
|
28
|
-
@metrics_processor.register_evaluation(target,
|
28
|
+
@metrics_processor.register_evaluation(target, feature_name, variation_identifier)
|
29
29
|
end
|
30
30
|
end
|
@@ -6,12 +6,9 @@ require_relative "../dto/target"
|
|
6
6
|
require_relative "../../sdk/version"
|
7
7
|
require_relative "../common/closeable"
|
8
8
|
require_relative "../common/sdk_codes"
|
9
|
-
require_relative "../api/metrics_event"
|
10
9
|
require_relative "../api/summary_metrics"
|
11
10
|
|
12
11
|
class MetricsProcessor < Closeable
|
13
|
-
GLOBAL_TARGET = Target.new(identifier: "__global__cf_target", name: "Global Target").freeze
|
14
|
-
|
15
12
|
def init(connector, config, callback)
|
16
13
|
|
17
14
|
unless connector.kind_of?(Connector)
|
@@ -79,8 +76,8 @@ class MetricsProcessor < Closeable
|
|
79
76
|
@config.logger.debug "Closing metrics processor"
|
80
77
|
end
|
81
78
|
|
82
|
-
def register_evaluation(target,
|
83
|
-
register_evaluation_metric(
|
79
|
+
def register_evaluation(target, feature_name, variation_identifier)
|
80
|
+
register_evaluation_metric(feature_name, variation_identifier)
|
84
81
|
if target
|
85
82
|
register_target_metric(target)
|
86
83
|
end
|
@@ -88,29 +85,24 @@ class MetricsProcessor < Closeable
|
|
88
85
|
|
89
86
|
private
|
90
87
|
|
91
|
-
def register_evaluation_metric(
|
88
|
+
def register_evaluation_metric(feature_name, variation_identifier)
|
92
89
|
# Guard clause to ensure feature_config, @global_target, and variation are valid.
|
93
90
|
# While they should be, this adds protection for an edge case we are seeing where the the ConcurrentMap (now replaced with our own thread safe hash)
|
94
91
|
# seemed to be accessing invalid areas of memory and seg faulting.
|
95
92
|
# Issue being tracked in FFM-12192, and once resolved, can remove these checks in a future release && once the issue is resolved.
|
96
|
-
|
97
|
-
@config.logger.warn("Skipping invalid MetricsEvent: feature_config is missing or incomplete. feature_config=#{
|
93
|
+
unless feature_name && !feature_name.empty?
|
94
|
+
@config.logger.warn("Skipping invalid MetricsEvent: feature_config is missing or incomplete. feature_config=#{feature_name.inspect}")
|
98
95
|
return
|
99
96
|
end
|
100
97
|
|
101
|
-
|
102
|
-
@config.logger.warn("Skipping
|
98
|
+
unless variation_identifier && !variation_identifier.empty?
|
99
|
+
@config.logger.warn("Skipping iInvalid MetricsEvent: variation is missing or incomplete. variation=#{variation_identifier.inspect}")
|
103
100
|
return
|
104
101
|
end
|
105
102
|
|
106
|
-
if variation.nil? || !variation.respond_to?(:identifier) || variation.identifier.nil?
|
107
|
-
@config.logger.warn("Skipping iInvalid MetricsEvent: variation is missing or incomplete. variation=#{variation.inspect}")
|
108
|
-
return
|
109
|
-
end
|
110
|
-
|
111
|
-
event = MetricsEvent.new(feature_config, GLOBAL_TARGET, variation, @config.logger)
|
112
103
|
@metric_maps_mutex.synchronize do
|
113
|
-
|
104
|
+
key = "#{feature_name}\0#{variation_identifier}"
|
105
|
+
@evaluation_metrics[key] = (@evaluation_metrics[key] || 0) + 1
|
114
106
|
end
|
115
107
|
end
|
116
108
|
|
@@ -185,31 +177,28 @@ class MetricsProcessor < Closeable
|
|
185
177
|
|
186
178
|
total_count = 0
|
187
179
|
evaluation_metrics_clone.each do |key, value|
|
188
|
-
|
189
|
-
|
190
|
-
#
|
191
|
-
#
|
192
|
-
|
193
|
-
|
194
|
-
#
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
# If any components are missing, log a detailed warning and skip processing
|
201
|
-
unless missing_components.empty?
|
202
|
-
@config.logger.warn "Skipping invalid metrics event: missing #{missing_components.join(', ')} in key: #{key.inspect}, full details: #{key.inspect}"
|
180
|
+
feature_name, variation_identifier = key.split("\0", 2)
|
181
|
+
|
182
|
+
# Although feature_name and variation_identifier should always be present,
|
183
|
+
# this guard provides protection against an edge case where keys reference
|
184
|
+
# other objects in memory. In versions <= 1.4.4, we were keying on the MetricsEvent
|
185
|
+
# class (now deleted). To remediate this, we have transitioned to using strings as keys.
|
186
|
+
# This issue is being tracked in FFM-12192. Once resolved, these checks can be safely
|
187
|
+
# removed in a future release.
|
188
|
+
# If any required data is missing, log a detailed warning and skip processing.
|
189
|
+
unless feature_name && variation_identifier && value.is_a?(Integer) && value > 0
|
190
|
+
@config.logger.warn "Skipping invalid metrics event: missing or invalid feature_name, variation_identifier, or count. Key: #{key.inspect}, Count: #{value.inspect}"
|
203
191
|
next
|
204
192
|
end
|
205
193
|
|
206
194
|
total_count += value
|
195
|
+
|
207
196
|
metrics_data = OpenapiClient::MetricsData.new({ :attributes => [] })
|
208
197
|
metrics_data.timestamp = (Time.now.to_f * 1000).to_i
|
209
198
|
metrics_data.count = value
|
210
199
|
metrics_data.metrics_type = "FFMETRICS"
|
211
|
-
metrics_data.attributes.push(OpenapiClient::KeyValue.new({ :key => @feature_name_attribute, :value =>
|
212
|
-
metrics_data.attributes.push(OpenapiClient::KeyValue.new({ :key => @variation_identifier_attribute, :value =>
|
200
|
+
metrics_data.attributes.push(OpenapiClient::KeyValue.new({ :key => @feature_name_attribute, :value => feature_name }))
|
201
|
+
metrics_data.attributes.push(OpenapiClient::KeyValue.new({ :key => @variation_identifier_attribute, :value => variation_identifier }))
|
213
202
|
metrics_data.attributes.push(OpenapiClient::KeyValue.new({ :key => @target_attribute, :value => @global_target_identifier }))
|
214
203
|
metrics_data.attributes.push(OpenapiClient::KeyValue.new({ :key => @sdk_type, :value => @server }))
|
215
204
|
metrics_data.attributes.push(OpenapiClient::KeyValue.new({ :key => @sdk_language, :value => "ruby" }))
|
data/lib/ff/ruby/server/sdk.rb
CHANGED
@@ -17,7 +17,6 @@ require_relative "sdk/api/cf_client"
|
|
17
17
|
require_relative "sdk/api/evaluation"
|
18
18
|
require_relative "sdk/api/inner_client"
|
19
19
|
require_relative "sdk/api/auth_service"
|
20
|
-
require_relative "sdk/api/metrics_event"
|
21
20
|
require_relative "sdk/api/default_cache"
|
22
21
|
require_relative "sdk/api/config_builder"
|
23
22
|
require_relative "sdk/api/file_map_store"
|
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.5
|
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-25 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rake
|
@@ -253,7 +253,6 @@ files:
|
|
253
253
|
- lib/ff/ruby/server/sdk/api/inner_client_repository_callback.rb
|
254
254
|
- lib/ff/ruby/server/sdk/api/inner_client_updater.rb
|
255
255
|
- lib/ff/ruby/server/sdk/api/metrics_callback.rb
|
256
|
-
- lib/ff/ruby/server/sdk/api/metrics_event.rb
|
257
256
|
- lib/ff/ruby/server/sdk/api/metrics_processor.rb
|
258
257
|
- lib/ff/ruby/server/sdk/api/operators.rb
|
259
258
|
- lib/ff/ruby/server/sdk/api/polling_processor.rb
|
@@ -1,53 +0,0 @@
|
|
1
|
-
class MetricsEvent
|
2
|
-
|
3
|
-
attr_accessor :feature_config, :target, :variation
|
4
|
-
|
5
|
-
def initialize(feature_config, target, variation, logger)
|
6
|
-
|
7
|
-
@target = target
|
8
|
-
@variation = variation
|
9
|
-
@feature_config = feature_config
|
10
|
-
@logger = logger
|
11
|
-
freeze
|
12
|
-
end
|
13
|
-
|
14
|
-
def ==(other)
|
15
|
-
eql?(other)
|
16
|
-
end
|
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
|
-
# We should always have a logger available except when we've deep cloned this class. We don't do any
|
25
|
-
# equality check on clones in metrics code anyway, so this is just a safety check.
|
26
|
-
if @logger
|
27
|
-
@logger.warn("Warning: Attempted to compare MetricsEvent with #{other.class.name}")
|
28
|
-
end
|
29
|
-
return false
|
30
|
-
end
|
31
|
-
|
32
|
-
feature_config.feature == other.feature_config.feature and
|
33
|
-
variation.identifier == other.variation.identifier and
|
34
|
-
target.identifier == other.target.identifier
|
35
|
-
end
|
36
|
-
|
37
|
-
def hash
|
38
|
-
feature_config.feature.hash | variation.identifier.hash | target.identifier.hash
|
39
|
-
end
|
40
|
-
|
41
|
-
|
42
|
-
# Exclude logger from serialization
|
43
|
-
def marshal_dump
|
44
|
-
[@feature_config, @target, @variation]
|
45
|
-
end
|
46
|
-
|
47
|
-
def marshal_load(array)
|
48
|
-
@feature_config, @target, @variation = array
|
49
|
-
@logger = nil
|
50
|
-
end
|
51
|
-
|
52
|
-
|
53
|
-
end
|