Add expires_in option for ActiveSupport::Cache::RedisStore#increment method (#7515)

* rails patch to fix expires_in for increment method

* fixup! rails patch to fix expires_in for increment method

correct test case

* fix redundant file name & class name

* add comment to explain monkey patch for RedisCacheStore#increment
This commit is contained in:
Tam Chau 2020-04-27 23:40:49 +09:00 committed by GitHub
parent b9a8d87e95
commit ffba42cf43
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 73 additions and 0 deletions

View file

@ -0,0 +1,25 @@
module ActiveSupport
module Cache
class RedisCacheStore
def increment(name, amount = 1, options = nil)
# With Rails 5.2.4, RedisCacheStore#increment method does not support option :expires_in.
# In order to workaround, we call expire command if the key is incremented at the first time.
# This patch should be removed when upgrading to Rails 6.
instrument :increment, name, amount: amount do
failsafe :increment do
options = merged_options(options)
key = normalize_key(name, options)
res = redis.with do |client|
client.incrby(key, amount).tap do
if options[:expires_in] && client.ttl(key).negative?
client.expire(key, options[:expires_in].to_i)
end
end
end
res
end
end
end
end
end
end

View file

@ -0,0 +1,48 @@
require "rails_helper"
RSpec.describe ActiveSupport::Cache::RedisCacheStore do
let(:redis_client) { ActiveSupport::Cache.lookup_store(:redis_cache_store).redis }
let(:cache_db) { described_class.new }
let(:key) { "monkey_patch_test" }
def value
cache_db.read(key, raw: true).to_i
end
def pttl
redis_client.pttl(key)
end
describe ".increment" do
before do
cache_db.delete(key)
end
it "increments value without expires_in" do
cache_db.increment(key)
expect(value).to eq(1)
expect(pttl).to eq(-1)
cache_db.increment(key)
expect(value).to eq(2)
expect(pttl).to eq(-1)
end
it "increments value with expires_in" do
cache_db.increment(key, 1, expires_in: 100.seconds)
first_pttl = pttl
expect(value).to eq(1)
expect(first_pttl > 0).to be_truthy
expect(first_pttl <= 100_000).to be_truthy
cache_db.increment(key, 1, expires_in: 200.seconds)
second_pttl = pttl
expect(value).to eq(2)
expect(second_pttl <= first_pttl).to be_truthy
end
end
end