Skip to content

Support cache stores without delete_matched#713

Open
rience wants to merge 1 commit intorack:mainfrom
rience:solid-cache-support
Open

Support cache stores without delete_matched#713
rience wants to merge 1 commit intorack:mainfrom
rience:solid-cache-support

Conversation

@rience
Copy link

@rience rience commented Mar 15, 2026

Summary

Rack::Attack.reset! no longer raises IncompatibleStoreError for cache stores that don't support delete_matched (e.g., SolidCache). Instead, it falls
back to a prefix rotation strategy that orphans old keys. Stores that fully support delete_matched are completely unaffected.

Motivation

SolidCache inherits from ActiveSupport::Cache::Store which defines delete_matched but raises NotImplementedError. This means reset! fails even though
all runtime operations (read, write, increment, delete) work fine. Since reset! is primarily a test helper for clearing state between runs, it
shouldn't make an otherwise functional store "incompatible".

How it works

  • reset! attempts to call delete_matched as before
  • If the store raises NotImplementedError (e.g., SolidCache inheriting ActiveSupport's stub) or NoMethodError (store doesn't define it at all), it falls
    back to prefix rotation
  • A generation counter is stored in the cache under "rack::attack:generation" and incremented on each fallback reset!
  • All key operations use an effective_prefix that includes the generation (e.g., rack::attack:g1:...) when generation > 0, making old keys inaccessible
  • The generation is read from the cache once on first access and memoized in memory — nearly zero runtime cost
  • Old keys are not deleted but expire naturally via TTL
  • IncompatibleStoreError remains defined but is no longer raised, avoiding breakage for code that rescues it

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant