Skip to content

Commit b54a287

Browse files
committed
Ensure all Cache store have consistent TTL behavior on increment
Make sure they all increment the counter but don't update the TTL.
1 parent 25b7f64 commit b54a287

File tree

2 files changed

+26
-7
lines changed

2 files changed

+26
-7
lines changed

activesupport/lib/active_support/cache/file_store.rb

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -211,17 +211,22 @@ def search_dir(dir, &callback)
211211
# If the key is not found it is created and set to +amount+.
212212
def modify_value(name, amount, options)
213213
file_name = normalize_key(name, options)
214+
options = merged_options(options)
215+
key = normalize_key(name, options)
216+
version = normalize_version(name, options)
217+
amount = Integer(amount)
214218

215219
lock_file(file_name) do
216-
options = merged_options(options)
220+
entry = read_entry(key, **options)
217221

218-
if num = read(name, options)
219-
num = num.to_i + amount
220-
write(name, num, options)
221-
num
222-
else
223-
write(name, Integer(amount), options)
222+
if !entry || entry.expired? || entry.mismatched?(version)
223+
write(name, amount, options)
224224
amount
225+
else
226+
num = entry.value.to_i + amount
227+
entry = Entry.new(num, expires_at: entry.expires_at, version: entry.version)
228+
write_entry(key, entry)
229+
num
225230
end
226231
end
227232
end

activesupport/test/cache/behaviors/cache_increment_decrement_behavior.rb

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,4 +30,18 @@ def test_decrement
3030
missing = @cache.decrement(SecureRandom.alphanumeric, 100)
3131
assert_equal @cache.is_a?(ActiveSupport::Cache::MemCacheStore) ? 0 : -100, missing
3232
end
33+
34+
def test_ttl_isnt_updated
35+
key = SecureRandom.uuid
36+
37+
assert_equal 1, @cache.increment(key, 1, expires_in: 1)
38+
assert_equal 2, @cache.increment(key, 1, expires_in: 5000)
39+
40+
# having to sleep two seconds in a test is bad, but we're testing
41+
# a wide range of backends with different TTL mecanisms, most without
42+
# subsecond granularity, so this is the only reliable way.
43+
sleep 2
44+
45+
assert_nil @cache.read(key, raw: true)
46+
end
3347
end

0 commit comments

Comments
 (0)