magick-feature-flags 0.9.27 → 0.9.29
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/registry.rb +18 -1
- data/lib/magick/admin_ui/engine.rb +5 -0
- data/lib/magick/feature.rb +5 -8
- data/lib/magick/version.rb +1 -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: f1083faa87c666482ed4ad7d0497e8ffcd7971f735ec1060d211f56e2ebbb756
|
|
4
|
+
data.tar.gz: 444ef7774e1f944f39f133ef8f6b37a94915574c54ec9b562e3623d5b1ab4d08
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: bd0f4cc40177fcf796461f84e4ff4b63fd569b5828d0ebc8c2d3c8130b4938db02f747e223858267e96c0ebd471d46e6e437efb97f8f073e888f05cdab737876
|
|
7
|
+
data.tar.gz: 8cd773acbaf174f5e96c9eed9f3103f241936ac61941cb533ab335df4d60bfc7fe13dab0e639b344715c4d0a358eb0c245ce4f038a54f67942acbb15fad9d338
|
|
@@ -15,6 +15,8 @@ module Magick
|
|
|
15
15
|
@primary = primary || :memory # :memory, :redis, or :active_record
|
|
16
16
|
@subscriber_thread = nil
|
|
17
17
|
@subscriber = nil
|
|
18
|
+
@last_reload_times = {} # Track last reload time per feature for debouncing
|
|
19
|
+
@reload_mutex = Mutex.new
|
|
18
20
|
# Only start Pub/Sub subscriber if Redis is available
|
|
19
21
|
# In memory-only mode, each process has isolated cache (no cross-process invalidation)
|
|
20
22
|
start_cache_invalidation_subscriber if redis_adapter
|
|
@@ -187,6 +189,21 @@ module Magick
|
|
|
187
189
|
on.message do |_channel, feature_name|
|
|
188
190
|
feature_name_str = feature_name.to_s
|
|
189
191
|
|
|
192
|
+
# Debounce: only reload if we haven't reloaded this feature in the last 100ms
|
|
193
|
+
# This prevents duplicate reloads from multiple invalidation messages
|
|
194
|
+
should_reload = @reload_mutex.synchronize do
|
|
195
|
+
last_reload = @last_reload_times[feature_name_str]
|
|
196
|
+
now = Time.now.to_f
|
|
197
|
+
if last_reload.nil? || (now - last_reload) > 0.1 # 100ms debounce
|
|
198
|
+
@last_reload_times[feature_name_str] = now
|
|
199
|
+
true
|
|
200
|
+
else
|
|
201
|
+
false
|
|
202
|
+
end
|
|
203
|
+
end
|
|
204
|
+
|
|
205
|
+
next unless should_reload
|
|
206
|
+
|
|
190
207
|
# Invalidate memory cache for this feature
|
|
191
208
|
memory_adapter.delete(feature_name_str) if memory_adapter
|
|
192
209
|
|
|
@@ -196,7 +213,7 @@ module Magick
|
|
|
196
213
|
feature = Magick.features[feature_name_str]
|
|
197
214
|
if feature.respond_to?(:reload)
|
|
198
215
|
feature.reload
|
|
199
|
-
# Log for debugging (only in development)
|
|
216
|
+
# Log for debugging (only in development, and only once per debounce period)
|
|
200
217
|
if defined?(Rails) && Rails.env.development?
|
|
201
218
|
Rails.logger.debug "Magick: Reloaded feature '#{feature_name_str}' after cache invalidation"
|
|
202
219
|
end
|
|
@@ -16,6 +16,11 @@ module Magick
|
|
|
16
16
|
|
|
17
17
|
engine_name 'magick_admin_ui'
|
|
18
18
|
|
|
19
|
+
# Ensure the engine doesn't interfere with Warden/Devise middleware
|
|
20
|
+
# Rails engines by default inherit middleware from the main app, which is what we want
|
|
21
|
+
# We don't add any custom middleware that could interfere with Warden/Devise
|
|
22
|
+
# The engine should work alongside existing authentication middleware without modification
|
|
23
|
+
|
|
19
24
|
# Rails engines automatically detect app/views and app/controllers directories
|
|
20
25
|
# With isolate_namespace, views should be at:
|
|
21
26
|
# app/views/magick/adminui/[controller]/[action].html.erb
|
data/lib/magick/feature.rb
CHANGED
|
@@ -563,6 +563,7 @@ module Magick
|
|
|
563
563
|
|
|
564
564
|
def save_targeting
|
|
565
565
|
# Save targeting to adapter (this updates memory synchronously, then Redis/AR)
|
|
566
|
+
# The set method already publishes cache invalidation to other processes via Pub/Sub
|
|
566
567
|
adapter_registry.set(name, 'targeting', targeting)
|
|
567
568
|
|
|
568
569
|
# Update the feature in Magick.features if it's registered
|
|
@@ -575,14 +576,10 @@ module Magick
|
|
|
575
576
|
# Update local targeting empty cache for performance
|
|
576
577
|
@_targeting_empty = targeting.empty?
|
|
577
578
|
|
|
578
|
-
#
|
|
579
|
-
#
|
|
580
|
-
#
|
|
581
|
-
# The set method
|
|
582
|
-
# it happens even if Redis update fails or is async
|
|
583
|
-
if adapter_registry.respond_to?(:publish_cache_invalidation)
|
|
584
|
-
adapter_registry.publish_cache_invalidation(name)
|
|
585
|
-
end
|
|
579
|
+
# Note: We don't need to explicitly publish cache invalidation here because:
|
|
580
|
+
# 1. adapter_registry.set already publishes cache invalidation (synchronously for async Redis updates)
|
|
581
|
+
# 2. Publishing twice causes duplicate reloads in other processes
|
|
582
|
+
# 3. The set method handles both sync and async Redis updates correctly
|
|
586
583
|
end
|
|
587
584
|
|
|
588
585
|
private
|
data/lib/magick/version.rb
CHANGED