magick-feature-flags 0.9.6 → 0.9.7

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: c89e62bee50614e51b3e844968d557e90217cd48e77bb68ec50c47d48881389b
4
- data.tar.gz: d39574add8463bb4a927ea94db047d3418317d966b77f400892f67ed6bf4a31c
3
+ metadata.gz: 015b9568cac92b03d1776240c7236cb395d15189eb496e03ac803979fef2d77d
4
+ data.tar.gz: 3219b3349bb202775c883d7b977ca0dd8d64846625a524abbe858c6d51d9db43
5
5
  SHA512:
6
- metadata.gz: 133bbce3e15f14c39181eaf2078e0bec80fcc2aa295d85397bcb78f95400637e046dd9749f5c8ed65291f2c2e8b562ac8ced6b3df39dd3d625536a58851cefbb
7
- data.tar.gz: 3a8578be1de567da37d0393e07302934176100bed9d9239bad978c757ed65a6f58770cc3a9b6b6fb5d73fd2393007053bc43c32b466b9bd167e97d5e775c6be0
6
+ metadata.gz: d93760f46cd383bc5b97f032a992fe4e0fc6e567d50985ab2544475805ffbb4545b105c8033a7aafb5a48149c1169ab7f87e6e70da58bcbfd2554a1935608bb3
7
+ data.tar.gz: 19424a6172af8421a2041a4259f5474a4cffa7cf62cd03582b23f479374b7ca3a9aa56ca57f69e7facae4e372662d70abf80384456247d801ffd6eee141acd56
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 enabled: true
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 will only be enabled if base_feature is also enabled
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 average duration for feature checks
326
- avg_duration = Magick.performance_metrics.average_duration(feature_name: :my_feature)
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
- most_used = Magick.performance_metrics.most_used_features(limit: 10)
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
- # Get usage count
332
- count = Magick.performance_metrics.usage_count(:my_feature)
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, both adapters are updated simultaneously.
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,15 @@ module Magick
48
48
  return unless enabled
49
49
 
50
50
  @performance_metrics = PerformanceMetrics.new(batch_size: batch_size, flush_interval: flush_interval)
51
- # Enable Redis tracking if Redis adapter is configured (or explicitly set)
52
- if redis_tracking.nil?
53
- # Auto-enable if Redis adapter exists
54
- redis_tracking = !@redis_url.nil? || configure_redis_adapter != nil
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
- @performance_metrics.enable_redis_tracking(enable: redis_tracking) if @performance_metrics
59
+ # If nil, will be auto-determined in apply! method
57
60
  end
58
61
 
59
62
  def audit_log(enabled: true, adapter: nil)
@@ -95,9 +98,15 @@ module Magick
95
98
  Magick.versioning = versioning if versioning
96
99
  Magick.warn_on_deprecated = warn_on_deprecated
97
100
 
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
+ # Enable Redis tracking for performance metrics
102
+ if Magick.performance_metrics
103
+ # If redis_tracking was explicitly set, use that value
104
+ if defined?(@performance_metrics_redis_tracking) && !@performance_metrics_redis_tracking.nil?
105
+ Magick.performance_metrics.enable_redis_tracking(enable: @performance_metrics_redis_tracking)
106
+ # Otherwise, auto-enable if Redis adapter is configured
107
+ elsif adapter_registry.is_a?(Adapters::Registry) && adapter_registry.redis_adapter
108
+ Magick.performance_metrics.enable_redis_tracking(enable: true)
109
+ end
101
110
  end
102
111
  end
103
112
 
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Magick
4
- VERSION = '0.9.6'
4
+ VERSION = '0.9.7'
5
5
  end
data/lib/magick.rb CHANGED
@@ -128,6 +128,38 @@ module Magick
128
128
  @versioning ||= Versioning.new(adapter_registry || default_adapter_registry)
129
129
  end
130
130
 
131
+ # Get total usage count for a feature (combines memory and Redis counts)
132
+ def feature_stats(feature_name)
133
+ return {} unless performance_metrics
134
+
135
+ {
136
+ usage_count: performance_metrics.usage_count(feature_name),
137
+ average_duration: performance_metrics.average_duration(feature_name: feature_name),
138
+ average_duration_by_operation: {
139
+ enabled: performance_metrics.average_duration(feature_name: feature_name, operation: 'enabled?'),
140
+ value: performance_metrics.average_duration(feature_name: feature_name, operation: 'value'),
141
+ get_value: performance_metrics.average_duration(feature_name: feature_name, operation: 'get_value')
142
+ }
143
+ }
144
+ end
145
+
146
+ # Get usage count for a feature
147
+ def feature_usage_count(feature_name)
148
+ performance_metrics&.usage_count(feature_name) || 0
149
+ end
150
+
151
+ # Get average duration for a feature (optionally filtered by operation)
152
+ def feature_average_duration(feature_name, operation: nil)
153
+ return 0.0 unless performance_metrics
154
+
155
+ performance_metrics.average_duration(feature_name: feature_name, operation: operation)
156
+ end
157
+
158
+ # Get most used features
159
+ def most_used_features(limit: 10)
160
+ performance_metrics&.most_used_features(limit: limit) || {}
161
+ end
162
+
131
163
  def reset!
132
164
  @features = {}
133
165
  @adapter_registry = nil
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: magick-feature-flags
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.6
4
+ version: 0.9.7
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andrew Lobanov