Caching solutions like MemCache
and Redis always preserve expiration,
while altering a value to avoid any discrepancies caused by it.
Previously, while incrementing
or decrementing an integer value in MemoryStore,
Rails used to reset the expires_in
associated with the entry, for eg-
Before
Let’s say, we are storing certain number of likes on a product
as a like_counter
in MemoryStore for 10 seconds.
Here, if we increment
or decrement the counter,
it is used to reset the TTL.
irb(main):004:0> cache = ActiveSupport::Cache.lookup_store(:memory_store)
irb(main):004:0> cache.write("like_counter", 1, raw: true, expires_in: 10.seconds)
irb(main):004:0> sleep(2.seconds)
irb(main):004:0> cache.increment("like_counter")
irb(main):004:0> sleep(8.seconds)
irb(main):004:0> cache.read("like_counter")
irb(main):004:0> 2
As we can see after 10 seconds, like_counter
should have been deleted from the store, however,
it still shows the incremented value because cache.increment("like_counter")
set the timer
again to 10 seconds.
After
Now, Rails preserves expires_in while incrementing or decrementing an integer value in MemoryStore.
irb(main):004:0> cache = ActiveSupport::Cache.lookup_store(:memory_store)
irb(main):004:0> cache.write("like_counter", 1, raw: true, expires_in: 10.seconds)
irb(main):004:0> sleep(2.seconds)
irb(main):004:0> cache.increment("like_counter")
irb(main):004:0> sleep(8.seconds)
irb(main):004:0> cache.read("like_counter")
irb(main):004:0> nil
As it can be seen,
though we had incremented the counter,
the key got expired after 10 seconds
and returned nil
Check out the PR for more details.