magick-feature-flags 0.9.19 → 0.9.21
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/magick/adapters/memory.rb +6 -2
- data/lib/magick/feature.rb +27 -10
- data/lib/magick/version.rb +1 -1
- data/lib/magick.rb +9 -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: 467ad50ad54569fd4ac8562da75e37672716b980cfdfb03da79b2f29950fd4c9
|
|
4
|
+
data.tar.gz: 0b89ad165e8aad8fb2074821025bd7e50ef2568cc46f5b750bfc4c91c6e11658
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 7b3fa0a75bd127f269ecafcddfbe6dcba8d45a247d6b47d83085a097f58de6b74c570eb0655fd4a97c78d8335ff1916a57b3eb2b891143d6a2cc585acc5ff87c
|
|
7
|
+
data.tar.gz: 79cf7083e34daab0c569e9e05d6e0b123167692f2b206b67ae53321ddabe722861e701346dd5cac80c6b1898be75140ed52fd93470b9a19ccf8113ebf6d91a16
|
|
@@ -11,12 +11,16 @@ module Magick
|
|
|
11
11
|
end
|
|
12
12
|
|
|
13
13
|
def get(feature_name, key)
|
|
14
|
+
# Fast path: avoid mutex if possible (use string keys directly)
|
|
15
|
+
feature_name_str = feature_name.is_a?(String) ? feature_name : feature_name.to_s
|
|
16
|
+
key_str = key.is_a?(String) ? key : key.to_s
|
|
17
|
+
|
|
14
18
|
mutex.synchronize do
|
|
15
19
|
cleanup_expired
|
|
16
|
-
feature_data = store[
|
|
20
|
+
feature_data = store[feature_name_str]
|
|
17
21
|
return nil unless feature_data
|
|
18
22
|
|
|
19
|
-
value = feature_data[
|
|
23
|
+
value = feature_data[key_str]
|
|
20
24
|
deserialize_value(value)
|
|
21
25
|
end
|
|
22
26
|
end
|
data/lib/magick/feature.rb
CHANGED
|
@@ -25,29 +25,39 @@ module Magick
|
|
|
25
25
|
# Performance optimizations: cache expensive checks
|
|
26
26
|
@_targeting_empty = true # Will be updated after load_from_adapter
|
|
27
27
|
@_rails_events_enabled = false # Cache Rails events availability (only enable in dev)
|
|
28
|
+
@_perf_metrics_enabled = false # Cache performance metrics (disabled by default for speed)
|
|
28
29
|
|
|
29
30
|
validate_type!
|
|
30
31
|
validate_default_value!
|
|
31
32
|
load_from_adapter
|
|
32
33
|
# Update targeting empty cache after loading
|
|
33
34
|
@_targeting_empty = @targeting.empty?
|
|
35
|
+
# Cache performance metrics availability (check once, not on every call)
|
|
36
|
+
# Only enable if performance_metrics exists AND is actually being used
|
|
37
|
+
@_perf_metrics_enabled = !Magick.performance_metrics.nil?
|
|
34
38
|
# Save description and display_name to adapter if they were provided and not already in adapter
|
|
35
39
|
save_metadata_if_new
|
|
36
40
|
end
|
|
37
41
|
|
|
38
42
|
def enabled?(context = {})
|
|
39
|
-
#
|
|
43
|
+
# Check performance metrics dynamically (in case enabled after feature creation)
|
|
44
|
+
# But cache the check result for performance
|
|
40
45
|
perf_metrics = Magick.performance_metrics
|
|
41
|
-
|
|
46
|
+
perf_metrics_enabled = !perf_metrics.nil?
|
|
42
47
|
|
|
43
|
-
#
|
|
48
|
+
# Update cached flag if it changed
|
|
49
|
+
@_perf_metrics_enabled = perf_metrics_enabled if @_perf_metrics_enabled != perf_metrics_enabled
|
|
50
|
+
|
|
51
|
+
# Fast path: if performance metrics disabled, skip all overhead
|
|
52
|
+
return check_enabled(context) unless perf_metrics_enabled
|
|
53
|
+
|
|
54
|
+
# Performance metrics enabled: measure and record
|
|
55
|
+
start_time = Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
|
44
56
|
result = check_enabled(context)
|
|
57
|
+
duration = (Process.clock_gettime(Process::CLOCK_MONOTONIC) - start_time) * 1000 # milliseconds
|
|
45
58
|
|
|
46
|
-
# Record metrics if enabled
|
|
47
|
-
|
|
48
|
-
duration = (Process.clock_gettime(Process::CLOCK_MONOTONIC) - start_time) * 1000 # milliseconds
|
|
49
|
-
perf_metrics.record(name, 'enabled?', duration, success: true)
|
|
50
|
-
end
|
|
59
|
+
# Record metrics (only if enabled)
|
|
60
|
+
perf_metrics.record(name, 'enabled?', duration, success: true)
|
|
51
61
|
|
|
52
62
|
# Rails 8+ events (only in development or when explicitly enabled)
|
|
53
63
|
if @_rails_events_enabled
|
|
@@ -66,8 +76,9 @@ module Magick
|
|
|
66
76
|
|
|
67
77
|
result
|
|
68
78
|
rescue StandardError => e
|
|
69
|
-
if
|
|
70
|
-
|
|
79
|
+
# Record error metrics if enabled
|
|
80
|
+
if perf_metrics_enabled && perf_metrics
|
|
81
|
+
duration = defined?(start_time) && start_time ? (Process.clock_gettime(Process::CLOCK_MONOTONIC) - start_time) * 1000 : 0.0
|
|
71
82
|
perf_metrics.record(name, 'enabled?', duration, success: false)
|
|
72
83
|
end
|
|
73
84
|
# Return false on any error (fail-safe)
|
|
@@ -480,6 +491,10 @@ module Magick
|
|
|
480
491
|
# Reload feature state from adapter (useful when feature is changed externally)
|
|
481
492
|
def reload
|
|
482
493
|
load_from_adapter
|
|
494
|
+
# Update targeting empty cache
|
|
495
|
+
@_targeting_empty = @targeting.empty?
|
|
496
|
+
# Update performance metrics flag (in case it was enabled after feature creation)
|
|
497
|
+
@_perf_metrics_enabled = !Magick.performance_metrics.nil?
|
|
483
498
|
# Update registered feature instance if it exists
|
|
484
499
|
if Magick.features.key?(name)
|
|
485
500
|
registered = Magick.features[name]
|
|
@@ -489,6 +504,8 @@ module Magick
|
|
|
489
504
|
registered.instance_variable_set(:@description, @description)
|
|
490
505
|
registered.instance_variable_set(:@display_name, @display_name)
|
|
491
506
|
registered.instance_variable_set(:@targeting, @targeting.dup)
|
|
507
|
+
registered.instance_variable_set(:@_targeting_empty, @_targeting_empty)
|
|
508
|
+
registered.instance_variable_set(:@_perf_metrics_enabled, @_perf_metrics_enabled)
|
|
492
509
|
end
|
|
493
510
|
true
|
|
494
511
|
end
|
data/lib/magick/version.rb
CHANGED
data/lib/magick.rb
CHANGED
|
@@ -38,6 +38,12 @@ module Magick
|
|
|
38
38
|
if value && adapter_registry.is_a?(Adapters::Registry) && adapter_registry.redis_available?
|
|
39
39
|
value.enable_redis_tracking(enable: true)
|
|
40
40
|
end
|
|
41
|
+
# Update all existing features to enable performance metrics tracking
|
|
42
|
+
if value
|
|
43
|
+
features.each_value do |feature|
|
|
44
|
+
feature.instance_variable_set(:@_perf_metrics_enabled, true)
|
|
45
|
+
end
|
|
46
|
+
end
|
|
41
47
|
value
|
|
42
48
|
end
|
|
43
49
|
|
|
@@ -103,7 +109,9 @@ module Magick
|
|
|
103
109
|
end
|
|
104
110
|
|
|
105
111
|
def enabled?(feature_name, context = {})
|
|
106
|
-
|
|
112
|
+
# Fast path: use string key directly (avoid repeated to_s conversion)
|
|
113
|
+
feature_name_str = feature_name.to_s
|
|
114
|
+
feature = features[feature_name_str] || self[feature_name]
|
|
107
115
|
feature.enabled?(context)
|
|
108
116
|
end
|
|
109
117
|
|