Skip to content

Commit b122345

Browse files
authored
Merge pull request rails#33932 from schneems/schneems/recyclable-key-support-cache
[close rails#33907] Error when using "recyclable" cache keys with a store that does not support it
2 parents 40eb569 + 3424bd8 commit b122345

File tree

8 files changed

+69
-0
lines changed

8 files changed

+69
-0
lines changed

activerecord/lib/active_record/railtie.rb

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,31 @@ class Railtie < Rails::Railtie # :nodoc:
8888
end
8989
end
9090

91+
initializer "Check for cache versioning support" do
92+
config.after_initialize do |app|
93+
ActiveSupport.on_load(:active_record) do
94+
if app.config.active_record.cache_versioning && Rails.cache
95+
unless Rails.cache.class.try(:supports_cache_versioning?)
96+
raise <<-end_error
97+
98+
You're using a cache store that doesn't support native cache versioning.
99+
Your best option is to upgrade to a newer version of #{Rails.cache.class}
100+
that supports cache versioning (#{Rails.cache.class}.supports_cache_versioning? #=> true).
101+
102+
Next best, switch to a different cache store that does support cache versioning:
103+
https://guides.rubyonrails.org/caching_with_rails.html#cache-stores.
104+
105+
To keep using the current cache store, you can turn off cache versioning entirely:
106+
107+
config.active_record.cache_versioning = false
108+
109+
end_error
110+
end
111+
end
112+
end
113+
end
114+
end
115+
91116
initializer "active_record.check_schema_cache_dump" do
92117
if config.active_record.delete(:use_schema_cache_dump)
93118
config.after_initialize do |app|

activesupport/lib/active_support/cache/file_store.rb

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,11 @@ def initialize(cache_path, options = nil)
2626
@cache_path = cache_path.to_s
2727
end
2828

29+
# Advertise cache versioning support.
30+
def self.supports_cache_versioning?
31+
true
32+
end
33+
2934
# Deletes all items from the cache. In this case it deletes all the entries in the specified
3035
# file store directory except for .keep or .gitkeep. Be careful which directory is specified in your
3136
# config file when using +FileStore+ because everything in that directory will be deleted.

activesupport/lib/active_support/cache/mem_cache_store.rb

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,11 @@ def write_entry(key, entry, options)
4747
end
4848
end
4949

50+
# Advertise cache versioning support.
51+
def self.supports_cache_versioning?
52+
true
53+
end
54+
5055
prepend Strategy::LocalCache
5156
prepend LocalCacheWithRaw
5257

activesupport/lib/active_support/cache/memory_store.rb

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,11 @@ def initialize(options = nil)
3030
@pruning = false
3131
end
3232

33+
# Advertise cache versioning support.
34+
def self.supports_cache_versioning?
35+
true
36+
end
37+
3338
# Delete all data stored in a given cache store.
3439
def clear(options = nil)
3540
synchronize do

activesupport/lib/active_support/cache/null_store.rb

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,11 @@ module Cache
1212
class NullStore < Store
1313
prepend Strategy::LocalCache
1414

15+
# Advertise cache versioning support.
16+
def self.supports_cache_versioning?
17+
true
18+
end
19+
1520
def clear(options = nil)
1621
end
1722

activesupport/lib/active_support/cache/redis_cache_store.rb

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,11 @@ class RedisCacheStore < Store
6666
SCAN_BATCH_SIZE = 1000
6767
private_constant :SCAN_BATCH_SIZE
6868

69+
# Advertise cache versioning support.
70+
def self.supports_cache_versioning?
71+
true
72+
end
73+
6974
# Support raw values in the local cache strategy.
7075
module LocalCacheWithRaw # :nodoc:
7176
private

railties/CHANGELOG.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,10 @@
1+
* Raise an error when "recyclable cache keys" are being used by a cache store
2+
that does not explicitly support it. Custom cache keys that do support this feature
3+
can bypass this error by implementing the `supports_cache_versioning?` method on their
4+
class and returning a truthy value.
5+
6+
*Richard Schneeman*
7+
18
* Support environment specific credentials file.
29

310
For `production` environment look first for `config/credentials/production.yml.enc` file that can be decrypted by

railties/test/application/configuration_test.rb

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,18 @@ class MyLogger < ::Logger
124124
assert_equal "MyLogger", Rails.application.config.logger.class.name
125125
end
126126

127+
test "raises an error if cache does not support recyclable cache keys" do
128+
build_app(initializers: true)
129+
add_to_env_config "production", "config.cache_store = Class.new {}.new"
130+
add_to_env_config "production", "config.active_record.cache_versioning = true"
131+
132+
error = assert_raise(RuntimeError) do
133+
app "production"
134+
end
135+
136+
assert_match(/You're using a cache/, error.message)
137+
end
138+
127139
test "a renders exception on pending migration" do
128140
add_to_config <<-RUBY
129141
config.active_record.migration_error = :page_load

0 commit comments

Comments
 (0)