diff --git a/activesupport/lib/active_support/cache/file_store.rb b/activesupport/lib/active_support/cache/file_store.rb index 95bd2e7eac0..821747f9650 100644 --- a/activesupport/lib/active_support/cache/file_store.rb +++ b/activesupport/lib/active_support/cache/file_store.rb @@ -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 diff --git a/activesupport/test/cache/behaviors/cache_increment_decrement_behavior.rb b/activesupport/test/cache/behaviors/cache_increment_decrement_behavior.rb index c139eea8512..7685fa98870 100644 --- a/activesupport/test/cache/behaviors/cache_increment_decrement_behavior.rb +++ b/activesupport/test/cache/behaviors/cache_increment_decrement_behavior.rb @@ -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