magick-feature-flags 0.9.27 → 0.9.28

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: 2d9899b591d5ec1be511af30b937a34c676afae3b82cb79bfdc902aadadf9064
4
- data.tar.gz: 2a0bdd7d7edac034d652a709dafa7e46d24f2674f0e2335bd50fc44755ab0238
3
+ metadata.gz: d975b9e4104eaeb39aad4a8814897971e399bce74e61797b0929cad1a6f5b9bb
4
+ data.tar.gz: 23f2fddf2fd1dce20c0508d79e75e1ba3723df9230b5c98bb7241073ea32fa2b
5
5
  SHA512:
6
- metadata.gz: 401bfd7caa17aca83411668f7ac024a734131dbd130f24628ee5ef0f34f6b45ac06ca118c0aa903d53ee09f045f081e272bcd09f21820e9c07c16edbdc9f81c3
7
- data.tar.gz: '08ad203ed9b79dcb39c5e6e6a79fa497332e52bd84482c629275ce43e38d77894ad31b2b0480feb4a27975a4317f16172182c60e73a5169888bf3ae716b6f140'
6
+ metadata.gz: bd8a642773a7d81cda3630c8479e877ba34b8fa4713711a4b9bc08a303b1a487b350c371360717fd14ec89d4f70aea12ca624b8347496cd053fd76879fc3bc0e
7
+ data.tar.gz: c8551a3a54cd555eb1ff161aab47d5a53c2058ab4df52f9dcb50075ecd24e599fd899acf544d494197c0b877a9a4f9e4300aadd402da70803ae0022c66071d1b
@@ -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
@@ -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
- # Explicitly publish cache invalidation to other processes via Pub/Sub
579
- # This ensures other Rails app instances/consoles invalidate their cache and reload
580
- # Note: We don't invalidate local cache here because we just updated it above
581
- # The set method publishes cache invalidation, but we also publish here to ensure
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
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Magick
4
- VERSION = '0.9.27'
4
+ VERSION = '0.9.28'
5
5
  end
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.27
4
+ version: 0.9.28
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andrew Lobanov