magick-feature-flags 0.9.6 → 0.9.8
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/README.md +64 -8
- data/lib/magick/adapters/registry.rb +5 -0
- data/lib/magick/config.rb +23 -11
- data/lib/magick/version.rb +1 -1
- data/lib/magick.rb +40 -0
- 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: a7f546b5a885a633524d3b0c405e296621f00eaeabb7b65339160c5aa0911ead
|
|
4
|
+
data.tar.gz: 07af571d3fdba904c122c5e8996c58fcaac31d515bd955f57aa640d66373376b
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 75608b0d581c01aa0a25a362bb45c6cdcb4e8b3ee0316663d1ec6e521b9af3099192d1e2a38fcc13ead9adb256c1fda09934fef749323fc7e94cbaa7daac7c3f
|
|
7
|
+
data.tar.gz: ca5643cbd9bdeffeb8c8e1116b4631c6bedde59c2bd050936a77b6bdece35fc67955608ecccba41a7eaaffe59da769a0b74c59f9cb57372fbd07b281c188b397
|
data/README.md
CHANGED
|
@@ -82,7 +82,12 @@ Magick.configure do
|
|
|
82
82
|
async_updates enabled: true
|
|
83
83
|
|
|
84
84
|
# Enable services
|
|
85
|
-
performance_metrics
|
|
85
|
+
performance_metrics(
|
|
86
|
+
enabled: true,
|
|
87
|
+
redis_tracking: true, # Auto-enabled if Redis is configured
|
|
88
|
+
batch_size: 100, # Flush after 100 updates
|
|
89
|
+
flush_interval: 60 # Or flush every 60 seconds
|
|
90
|
+
)
|
|
86
91
|
audit_log enabled: true
|
|
87
92
|
versioning enabled: true
|
|
88
93
|
warn_on_deprecated enabled: true
|
|
@@ -295,7 +300,16 @@ variant = feature.get_variant
|
|
|
295
300
|
```ruby
|
|
296
301
|
feature = Magick[:advanced_feature]
|
|
297
302
|
feature.add_dependency(:base_feature)
|
|
298
|
-
# advanced_feature
|
|
303
|
+
# advanced_feature can be enabled independently
|
|
304
|
+
# However, base_feature (dependency) cannot be enabled if advanced_feature (main feature) is disabled
|
|
305
|
+
# This ensures dependencies are only enabled when their parent features are enabled
|
|
306
|
+
|
|
307
|
+
# Example:
|
|
308
|
+
Magick[:advanced_feature].disable # => true
|
|
309
|
+
Magick[:base_feature].enable # => false (cannot enable dependency when main feature is disabled)
|
|
310
|
+
|
|
311
|
+
Magick[:advanced_feature].enable # => true
|
|
312
|
+
Magick[:base_feature].enable # => true (now can enable dependency)
|
|
299
313
|
```
|
|
300
314
|
|
|
301
315
|
#### Export/Import
|
|
@@ -322,16 +336,55 @@ Magick.versioning.rollback(:my_feature, version: 2)
|
|
|
322
336
|
#### Performance Metrics
|
|
323
337
|
|
|
324
338
|
```ruby
|
|
325
|
-
# Get
|
|
326
|
-
|
|
339
|
+
# Get comprehensive stats for a feature
|
|
340
|
+
Magick.feature_stats(:my_feature)
|
|
341
|
+
# => {
|
|
342
|
+
# usage_count: 1250,
|
|
343
|
+
# average_duration: 0.032,
|
|
344
|
+
# average_duration_by_operation: {
|
|
345
|
+
# enabled: 0.032,
|
|
346
|
+
# value: 0.0,
|
|
347
|
+
# get_value: 0.0
|
|
348
|
+
# }
|
|
349
|
+
# }
|
|
350
|
+
|
|
351
|
+
# Get just the usage count
|
|
352
|
+
Magick.feature_usage_count(:my_feature)
|
|
353
|
+
# => 1250
|
|
354
|
+
|
|
355
|
+
# Get average duration (optionally filtered by operation)
|
|
356
|
+
Magick.feature_average_duration(:my_feature)
|
|
357
|
+
Magick.feature_average_duration(:my_feature, operation: 'enabled?')
|
|
327
358
|
|
|
328
359
|
# Get most used features
|
|
329
|
-
|
|
360
|
+
Magick.most_used_features(limit: 10)
|
|
361
|
+
# => {
|
|
362
|
+
# "my_feature" => 1250,
|
|
363
|
+
# "another_feature" => 890,
|
|
364
|
+
# ...
|
|
365
|
+
# }
|
|
366
|
+
|
|
367
|
+
# Direct access to performance metrics (for advanced usage)
|
|
368
|
+
Magick.performance_metrics.average_duration(feature_name: :my_feature)
|
|
369
|
+
Magick.performance_metrics.usage_count(:my_feature)
|
|
370
|
+
Magick.performance_metrics.most_used_features(limit: 10)
|
|
371
|
+
```
|
|
372
|
+
|
|
373
|
+
**Configuration:**
|
|
330
374
|
|
|
331
|
-
|
|
332
|
-
|
|
375
|
+
```ruby
|
|
376
|
+
Magick.configure do
|
|
377
|
+
performance_metrics(
|
|
378
|
+
enabled: true,
|
|
379
|
+
redis_tracking: true, # Auto-enabled if Redis is configured
|
|
380
|
+
batch_size: 100, # Flush after 100 updates
|
|
381
|
+
flush_interval: 60 # Or flush every 60 seconds
|
|
382
|
+
)
|
|
383
|
+
end
|
|
333
384
|
```
|
|
334
385
|
|
|
386
|
+
**Note:** When `redis_tracking: true` is set, usage counts are persisted to Redis and aggregated across all processes, giving you total usage statistics.
|
|
387
|
+
|
|
335
388
|
#### Audit Logging
|
|
336
389
|
|
|
337
390
|
```ruby
|
|
@@ -351,7 +404,10 @@ Magick uses a dual-adapter strategy:
|
|
|
351
404
|
1. **Memory Adapter**: Fast, in-memory storage with TTL support
|
|
352
405
|
2. **Redis Adapter**: Persistent storage for distributed systems (optional)
|
|
353
406
|
|
|
354
|
-
The registry automatically falls back from memory to Redis if a feature isn't found in memory. When features are updated
|
|
407
|
+
The registry automatically falls back from memory to Redis if a feature isn't found in memory. When features are updated:
|
|
408
|
+
- Both adapters are updated simultaneously
|
|
409
|
+
- Cache invalidation messages are published via Redis Pub/Sub to notify other processes
|
|
410
|
+
- Targeting updates trigger immediate cache invalidation to ensure consistency
|
|
355
411
|
|
|
356
412
|
#### Memory-Only Mode
|
|
357
413
|
|
data/lib/magick/config.rb
CHANGED
|
@@ -48,12 +48,16 @@ module Magick
|
|
|
48
48
|
return unless enabled
|
|
49
49
|
|
|
50
50
|
@performance_metrics = PerformanceMetrics.new(batch_size: batch_size, flush_interval: flush_interval)
|
|
51
|
-
#
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
51
|
+
# Store redis_tracking preference for later application
|
|
52
|
+
@performance_metrics_redis_tracking = redis_tracking
|
|
53
|
+
# Enable Redis tracking if explicitly set to true, otherwise defer to apply! method
|
|
54
|
+
if redis_tracking == true
|
|
55
|
+
@performance_metrics.enable_redis_tracking(enable: true)
|
|
56
|
+
elsif redis_tracking == false
|
|
57
|
+
@performance_metrics.enable_redis_tracking(enable: false)
|
|
55
58
|
end
|
|
56
|
-
|
|
59
|
+
# If nil, will be auto-determined in apply! method
|
|
60
|
+
@performance_metrics
|
|
57
61
|
end
|
|
58
62
|
|
|
59
63
|
def audit_log(enabled: true, adapter: nil)
|
|
@@ -90,15 +94,23 @@ module Magick
|
|
|
90
94
|
def apply!
|
|
91
95
|
# Apply configuration to Magick module
|
|
92
96
|
Magick.adapter_registry = adapter_registry if adapter_registry
|
|
93
|
-
|
|
97
|
+
|
|
98
|
+
# Apply performance metrics (preserve redis_tracking setting)
|
|
99
|
+
if performance_metrics
|
|
100
|
+
Magick.performance_metrics = performance_metrics
|
|
101
|
+
# Re-apply redis_tracking setting after assignment (in case object was replaced)
|
|
102
|
+
if defined?(@performance_metrics_redis_tracking) && !@performance_metrics_redis_tracking.nil?
|
|
103
|
+
Magick.performance_metrics.enable_redis_tracking(enable: @performance_metrics_redis_tracking)
|
|
104
|
+
# Otherwise, auto-enable if Redis adapter is configured
|
|
105
|
+
# Check Magick.adapter_registry (after it's been set) instead of local instance variable
|
|
106
|
+
elsif Magick.adapter_registry.is_a?(Adapters::Registry) && Magick.adapter_registry.redis_available?
|
|
107
|
+
Magick.performance_metrics.enable_redis_tracking(enable: true)
|
|
108
|
+
end
|
|
109
|
+
end
|
|
110
|
+
|
|
94
111
|
Magick.audit_log = audit_log if audit_log
|
|
95
112
|
Magick.versioning = versioning if versioning
|
|
96
113
|
Magick.warn_on_deprecated = warn_on_deprecated
|
|
97
|
-
|
|
98
|
-
# Enable Redis tracking for performance metrics if Redis adapter is configured
|
|
99
|
-
if Magick.performance_metrics && adapter_registry.is_a?(Adapters::Registry) && adapter_registry.redis_adapter
|
|
100
|
-
Magick.performance_metrics.enable_redis_tracking(enable: true)
|
|
101
|
-
end
|
|
102
114
|
end
|
|
103
115
|
|
|
104
116
|
private
|
data/lib/magick/version.rb
CHANGED
data/lib/magick.rb
CHANGED
|
@@ -128,6 +128,46 @@ module Magick
|
|
|
128
128
|
@versioning ||= Versioning.new(adapter_registry || default_adapter_registry)
|
|
129
129
|
end
|
|
130
130
|
|
|
131
|
+
# Manually enable Redis tracking for performance metrics
|
|
132
|
+
# Useful if Redis adapter becomes available after initial configuration
|
|
133
|
+
def enable_redis_tracking(enable: true)
|
|
134
|
+
return unless performance_metrics
|
|
135
|
+
|
|
136
|
+
performance_metrics.enable_redis_tracking(enable: enable)
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
# Get total usage count for a feature (combines memory and Redis counts)
|
|
140
|
+
def feature_stats(feature_name)
|
|
141
|
+
return {} unless performance_metrics
|
|
142
|
+
|
|
143
|
+
{
|
|
144
|
+
usage_count: performance_metrics.usage_count(feature_name),
|
|
145
|
+
average_duration: performance_metrics.average_duration(feature_name: feature_name),
|
|
146
|
+
average_duration_by_operation: {
|
|
147
|
+
enabled: performance_metrics.average_duration(feature_name: feature_name, operation: 'enabled?'),
|
|
148
|
+
value: performance_metrics.average_duration(feature_name: feature_name, operation: 'value'),
|
|
149
|
+
get_value: performance_metrics.average_duration(feature_name: feature_name, operation: 'get_value')
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
end
|
|
153
|
+
|
|
154
|
+
# Get usage count for a feature
|
|
155
|
+
def feature_usage_count(feature_name)
|
|
156
|
+
performance_metrics&.usage_count(feature_name) || 0
|
|
157
|
+
end
|
|
158
|
+
|
|
159
|
+
# Get average duration for a feature (optionally filtered by operation)
|
|
160
|
+
def feature_average_duration(feature_name, operation: nil)
|
|
161
|
+
return 0.0 unless performance_metrics
|
|
162
|
+
|
|
163
|
+
performance_metrics.average_duration(feature_name: feature_name, operation: operation)
|
|
164
|
+
end
|
|
165
|
+
|
|
166
|
+
# Get most used features
|
|
167
|
+
def most_used_features(limit: 10)
|
|
168
|
+
performance_metrics&.most_used_features(limit: limit) || {}
|
|
169
|
+
end
|
|
170
|
+
|
|
131
171
|
def reset!
|
|
132
172
|
@features = {}
|
|
133
173
|
@adapter_registry = nil
|