1
0
Fork 0
mirror of https://github.com/rails/rails.git synced 2022-11-09 12:12:34 -05:00

[close #33907] Error when using "recyclable" cache keys with a store that does not support it

If you are using the "in cache versioning" also known as "recyclable cache keys" the cache store must be aware of this scheme, otherwise you will generate cache entries that never invalidate.

This PR adds a check to the initialization process to ensure that if recyclable cache keys are being used via 

```
config.active_record.cache_versioning = true
```

Then the cache store needs to show that it supports this versioning scheme. Cache stores can let Rails know that they support this scheme by adding a method `supports_in_cache_versioning?` and returning true.
This commit is contained in:
schneems 2018-09-20 13:56:07 -05:00
parent b45b96b91f
commit 135d3e15b7
8 changed files with 75 additions and 0 deletions

View file

@ -88,6 +88,29 @@ module ActiveRecord
end
end
initializer "Check for cache versioning support" do
config.after_initialize do |app|
ActiveSupport.on_load(:active_record) do
if app.config.active_record.cache_versioning && Rails.cache
unless Rails.cache.try(:supports_in_cache_versioning?)
raise <<-end_error
You're using a cache store `#{Rails.cache.class}` that does not support
"recyclable" cache keys, also known as "in cache versioning". To
fix this issue either disable "recyclable" cache keys by setting:
config.active_record.cache_versioning = false
Or switching to a cache store that supports this functionality:
https://guides.rubyonrails.org/caching_with_rails.html#cache-stores
end_error
end
end
end
end
end
initializer "active_record.check_schema_cache_dump" do
if config.active_record.delete(:use_schema_cache_dump)
config.after_initialize do |app|

View file

@ -26,6 +26,13 @@ module ActiveSupport
@cache_path = cache_path.to_s
end
# Advertise that this cache store can be used
# with "recyclable cache keys" otherwise known
# as cache versioning.
def supports_in_cache_versioning?
true
end
# Deletes all items from the cache. In this case it deletes all the entries in the specified
# file store directory except for .keep or .gitkeep. Be careful which directory is specified in your
# config file when using +FileStore+ because everything in that directory will be deleted.

View file

@ -47,6 +47,13 @@ module ActiveSupport
end
end
# Advertise that this cache store can be used
# with "recyclable cache keys" otherwise known
# as cache versioning.
def supports_in_cache_versioning?
true
end
prepend Strategy::LocalCache
prepend LocalCacheWithRaw

View file

@ -30,6 +30,13 @@ module ActiveSupport
@pruning = false
end
# Advertise that this cache store can be used
# with "recyclable cache keys" otherwise known
# as cache versioning.
def supports_in_cache_versioning?
true
end
# Delete all data stored in a given cache store.
def clear(options = nil)
synchronize do

View file

@ -12,6 +12,13 @@ module ActiveSupport
class NullStore < Store
prepend Strategy::LocalCache
# Advertise that this cache store can be used
# with "recyclable cache keys" otherwise known
# as cache versioning.
def supports_in_cache_versioning?
true
end
def clear(options = nil)
end

View file

@ -66,6 +66,13 @@ module ActiveSupport
SCAN_BATCH_SIZE = 1000
private_constant :SCAN_BATCH_SIZE
# Advertise that this cache store can be used
# with "recyclable cache keys" otherwise known
# as cache versioning.
def supports_in_cache_versioning?
true
end
# Support raw values in the local cache strategy.
module LocalCacheWithRaw # :nodoc:
private

View file

@ -1,3 +1,8 @@
* Raise an error when "recyclable cache keys" are being used by a cache store
that does not explicitly support it.
*Richard Schneeman*
* Support environment specific credentials file.
For `production` environment look first for `config/credentials/production.yml.enc` file that can be decrypted by

View file

@ -124,6 +124,18 @@ module ApplicationTests
assert_equal "MyLogger", Rails.application.config.logger.class.name
end
test "raises an error if cache does not support recyclable cache keys" do
build_app(initializers: true)
add_to_env_config "production", "config.cache_store = Class.new {}.new"
add_to_env_config "production", "config.active_record.cache_versioning = true"
error = assert_raise(RuntimeError) do
app "production"
end
assert_match(/You're using a cache store/, error.message)
end
test "a renders exception on pending migration" do
add_to_config <<-RUBY
config.active_record.migration_error = :page_load