Ensure all Cache store have consistent TTL behavior on increment

Make sure they all increment the counter but don't update the TTL.
This commit is contained in:
Jean Boussier 2024-01-17 14:53:41 +01:00
parent 25b7f64074
commit b54a287f9d
2 changed files with 26 additions and 7 deletions

View File

@ -211,17 +211,22 @@ module ActiveSupport
# If the key is not found it is created and set to +amount+.
def modify_value(name, amount, options)
file_name = normalize_key(name, options)
options = merged_options(options)
key = normalize_key(name, options)
version = normalize_version(name, options)
amount = Integer(amount)
lock_file(file_name) do
options = merged_options(options)
entry = read_entry(key, **options)
if num = read(name, options)
num = num.to_i + amount
write(name, num, options)
num
else
write(name, Integer(amount), options)
if !entry || entry.expired? || entry.mismatched?(version)
write(name, amount, options)
amount
else
num = entry.value.to_i + amount
entry = Entry.new(num, expires_at: entry.expires_at, version: entry.version)
write_entry(key, entry)
num
end
end
end

View File

@ -30,4 +30,18 @@ module CacheIncrementDecrementBehavior
missing = @cache.decrement(SecureRandom.alphanumeric, 100)
assert_equal @cache.is_a?(ActiveSupport::Cache::MemCacheStore) ? 0 : -100, missing
end
def test_ttl_isnt_updated
key = SecureRandom.uuid
assert_equal 1, @cache.increment(key, 1, expires_in: 1)
assert_equal 2, @cache.increment(key, 1, expires_in: 5000)
# having to sleep two seconds in a test is bad, but we're testing
# a wide range of backends with different TTL mecanisms, most without
# subsecond granularity, so this is the only reliable way.
sleep 2
assert_nil @cache.read(key, raw: true)
end
end