Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ require "redis_cache_store"
It's important to note that Redis cache value must be string.

```crystal
cache = Cache::RedisCacheStore(String, String).new(expires_in: 1.minute, namespace: "myapp-cache")
cache = Cache::RedisCacheStore(String).new(expires_in: 1.minute, namespace: "myapp-cache")
# Fetches data from the Redis, using "myapp-cache:today" key. If there is data in
# the Redis with the given key, then that data is returned.
Expand Down Expand Up @@ -65,7 +65,7 @@ If you need to connect to a remote server or a different port, try:
```crystal
redis_uri = URI.parse("rediss://:my-secret-pw@10.0.1.1:6380/1")
redis = Redis::Client.new(uri: redis_uri)
cache = Cache::RedisCacheStore(String, String).new(expires_in: 1.minute, cache: redis)
cache = Cache::RedisCacheStore(String).new(expires_in: 1.minute, cache: redis)
```

## Contributing
Expand Down
2 changes: 1 addition & 1 deletion shard.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ authors:
dependencies:
cache:
github: crystal-cache/cache
version: ">= 0.15.0"
version: ">= 1.0.0"
redis:
github: jgaskins/redis

Expand Down
66 changes: 33 additions & 33 deletions spec/redis_cache_store_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -9,62 +9,62 @@ describe Cache do

context "#initialize" do
it "initialize" do
store = Cache::RedisCacheStore(String, String).new(expires_in: 12.hours)
store = Cache::RedisCacheStore(String).new(expires_in: 12.hours)

store.should be_a(Cache::RedisCacheStore(String, String))
store.should be_a(Cache::RedisCacheStore(String))
end

it "initialize with Redis::Client" do
redis_uri = URI.parse("redis://localhost:6379/1")
redis = Redis::Client.new(uri: redis_uri)
store = Cache::RedisCacheStore(String, String).new(expires_in: 12.hours, cache: redis)
store = Cache::RedisCacheStore(String).new(expires_in: 12.hours, cache: redis)

store.should be_a(Cache::RedisCacheStore(String, String))
store.should be_a(Cache::RedisCacheStore(String))
end
end

context "instance methods" do
it "#inspect without namescape" do
store = Cache::RedisCacheStore(String, String).new(expires_in: 12.hours)
store = Cache::RedisCacheStore(String).new(expires_in: 12.hours)

store.inspect.should match(
/\A#<Cache\:\:RedisCacheStore\(String, String\) redis=#<Redis\:\:Client\:0x.*expires_in=12:00:00.*namespace=nil>\z/
/\A#<Cache\:\:RedisCacheStore\(String\) redis=#<Redis\:\:Client\:0x.*expires_in=12:00:00.*namespace=nil>\z/
)
end

it "#inspect with namescape" do
store = Cache::RedisCacheStore(String, String).new(expires_in: 12.hours, namespace: "myapp-cache")
store = Cache::RedisCacheStore(String).new(expires_in: 12.hours, namespace: "myapp-cache")

store.inspect.should match(
/\A#<Cache\:\:RedisCacheStore\(String, String\) redis=#<Redis\:\:Client\:0x.*expires_in=12:00:00.*namespace=\"myapp-cache\">\z/
/\A#<Cache\:\:RedisCacheStore\(String\) redis=#<Redis\:\:Client\:0x.*expires_in=12:00:00.*namespace=\"myapp-cache\">\z/
)
end

it "#redis" do
store = Cache::RedisCacheStore(String, String).new(expires_in: 12.hours)
store = Cache::RedisCacheStore(String).new(expires_in: 12.hours)
store.redis.should be_a(Redis::Client)
end

it "#expires_in" do
store = Cache::RedisCacheStore(String, String).new(expires_in: 12.hours)
store = Cache::RedisCacheStore(String).new(expires_in: 12.hours)
store.expires_in.should eq(12.hours)
end

it "#namespace" do
store = Cache::RedisCacheStore(String, String).new(expires_in: 12.hours, namespace: "myapp-cache")
store = Cache::RedisCacheStore(String).new(expires_in: 12.hours, namespace: "myapp-cache")
store.namespace.should eq("myapp-cache")
end
end

it "write to cache first time" do
store = Cache::RedisCacheStore(String, String).new(12.hours)
store = Cache::RedisCacheStore(String).new(12.hours)

value = store.fetch("foo") { "bar" }
value.should eq("bar")
end

it "fetch from cache" do
store = Cache::RedisCacheStore(String, String).new(12.hours)
store = Cache::RedisCacheStore(String).new(12.hours)

value = store.fetch("foo") { "bar" }
value.should eq("bar")
Expand All @@ -76,7 +76,7 @@ describe Cache do
it "fetch from cache with custom Redis::Client" do
redis_uri = URI.parse("redis://localhost:6379/1")
redis = Redis::Client.new(uri: redis_uri)
store = Cache::RedisCacheStore(String, String).new(expires_in: 12.hours, cache: redis)
store = Cache::RedisCacheStore(String).new(expires_in: 12.hours, cache: redis)

value = store.fetch("foo") { "bar" }
value.should eq("bar")
Expand All @@ -86,7 +86,7 @@ describe Cache do
end

it "don't fetch from cache if expired" do
store = Cache::RedisCacheStore(String, String).new(1.seconds)
store = Cache::RedisCacheStore(String).new(1.seconds)

value = store.fetch("foo") { "bar" }
value.should eq("bar")
Expand All @@ -98,7 +98,7 @@ describe Cache do
end

it "fetch with expires_in from cache" do
store = Cache::RedisCacheStore(String, String).new(1.seconds)
store = Cache::RedisCacheStore(String).new(1.seconds)

value = store.fetch("foo", expires_in: 1.hours) { "bar" }
value.should eq("bar")
Expand All @@ -110,7 +110,7 @@ describe Cache do
end

it "don't fetch with expires_in from cache if expires" do
store = Cache::RedisCacheStore(String, String).new(12.hours)
store = Cache::RedisCacheStore(String).new(12.hours)

value = store.fetch("foo", expires_in: 1.seconds) { "bar" }
value.should eq("bar")
Expand All @@ -122,15 +122,15 @@ describe Cache do
end

it "write" do
store = Cache::RedisCacheStore(String, String).new(12.hours)
store = Cache::RedisCacheStore(String).new(12.hours)
store.write("foo", "bar", expires_in: 1.minute)

value = store.fetch("foo") { "bar" }
value.should eq("bar")
end

it "rewrite value" do
store = Cache::RedisCacheStore(String, String).new(12.hours)
store = Cache::RedisCacheStore(String).new(12.hours)
store.write("foo", "bar", expires_in: 1.minute)
store.write("foo", "baz", expires_in: 1.minute)

Expand All @@ -139,15 +139,15 @@ describe Cache do
end

it "read" do
store = Cache::RedisCacheStore(String, String).new(12.hours)
store = Cache::RedisCacheStore(String).new(12.hours)
store.write("foo", "bar")

value = store.read("foo")
value.should eq("bar")
end

it "set a custom expires_in value for entry on write" do
store = Cache::RedisCacheStore(String, String).new(12.hours)
store = Cache::RedisCacheStore(String).new(12.hours)
store.write("foo", "bar", expires_in: 1.second)

store.keys.should eq(Set{"foo"})
Expand All @@ -161,7 +161,7 @@ describe Cache do
end

it "delete from cache" do
store = Cache::RedisCacheStore(String, String).new(12.hours)
store = Cache::RedisCacheStore(String).new(12.hours)

value = store.fetch("foo") { "bar" }
value.should eq("bar")
Expand All @@ -175,7 +175,7 @@ describe Cache do
end

it "deletes all items from the cache" do
store = Cache::RedisCacheStore(String, String).new(12.hours)
store = Cache::RedisCacheStore(String).new(12.hours)

value = store.fetch("foo") { "bar" }
value.should eq("bar")
Expand All @@ -188,7 +188,7 @@ describe Cache do
end

it "#exists?" do
store = Cache::RedisCacheStore(String, String).new(12.hours)
store = Cache::RedisCacheStore(String).new(12.hours)

store.write("foo", "bar")

Expand All @@ -197,7 +197,7 @@ describe Cache do
end

it "#exists? expires" do
store = Cache::RedisCacheStore(String, String).new(1.second)
store = Cache::RedisCacheStore(String).new(1.second)

store.write("foo", "bar")

Expand All @@ -207,7 +207,7 @@ describe Cache do
end

it "#increment" do
store = Cache::RedisCacheStore(String, Int32).new(12.hours)
store = Cache::RedisCacheStore(Int32).new(12.hours)

store.write("num", 1)
store.increment("num", 1)
Expand All @@ -218,7 +218,7 @@ describe Cache do
end

it "#decrement" do
store = Cache::RedisCacheStore(String, Int32).new(12.hours)
store = Cache::RedisCacheStore(Int32).new(12.hours)

store.write("num", 2)
store.decrement("num", 1)
Expand All @@ -229,7 +229,7 @@ describe Cache do
end

it "#increment non-existent value" do
store = Cache::RedisCacheStore(String, Int32).new(12.hours)
store = Cache::RedisCacheStore(Int32).new(12.hours)

store.increment("undef_num", 1)

Expand All @@ -239,7 +239,7 @@ describe Cache do
end

it "clear" do
store = Cache::RedisCacheStore(String, String).new(12.hours)
store = Cache::RedisCacheStore(String).new(12.hours)

store.write("foo", "bar", expires_in: 1.minute)

Expand All @@ -251,10 +251,10 @@ describe Cache do

context "with namespace" do
it "write" do
store1 = Cache::RedisCacheStore(String, String).new(12.hours, namespace: "myapp-cache")
store1 = Cache::RedisCacheStore(String).new(12.hours, namespace: "myapp-cache")
store1.write("foo1", "bar", expires_in: 1.minute)

store2 = Cache::RedisCacheStore(String, String).new(12.hours)
store2 = Cache::RedisCacheStore(String).new(12.hours)
store2.write("foo1", "baz", expires_in: 1.minute)

store1.keys.should eq(Set{"foo1"})
Expand All @@ -265,8 +265,8 @@ describe Cache do
end

it "clear" do
store = Cache::RedisCacheStore(String, String).new(12.hours, namespace: "myapp-cache")
other_store = Cache::RedisCacheStore(String, String).new(12.hours, namespace: "other-cache")
store = Cache::RedisCacheStore(String).new(12.hours, namespace: "myapp-cache")
other_store = Cache::RedisCacheStore(String).new(12.hours, namespace: "other-cache")

1001.times do |i|
store.write("#{i + 1}", "bar", expires_in: 1.minute)
Expand Down
28 changes: 14 additions & 14 deletions src/redis_cache_store.cr
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ module Cache
# A cache store implementation which stores data in Redis.
#
# ```
# cache = Cache::RedisCacheStore(String, String).new(expires_in: 1.minute, namespace: "myapp-cache")
# cache = Cache::RedisCacheStore(String).new(expires_in: 1.minute, namespace: "myapp-cache")
#
# # Fetches data from the Redis, using "myapp-cache:today" key. If there is data in
# # the REdis with the given key, then that data is returned.
Expand All @@ -27,9 +27,9 @@ module Cache
# ```
# redis_uri = URI.parse("rediss://:my-secret-pw@10.0.1.1:6380/1")
# redis = Redis::Client.new(uri: redis_uri)
# cache = Cache::RedisCacheStore(String, String).new(expires_in: 1.minute, cache: redis)
# cache = Cache::RedisCacheStore(String).new(expires_in: 1.minute, cache: redis)
# ```
struct RedisCacheStore(K, V) < Store(K, V)
struct RedisCacheStore(V) < Store(V)
@cache : Redis::Client

# The maximum number of entries to receive per SCAN call.
Expand All @@ -43,33 +43,33 @@ module Cache
# server is shared with other apps:
#
# ```
# Cache::RedisCacheStore(String, String).new(expires_in: 1.minute, namespace: "myapp-cache")
# Cache::RedisCacheStore(String).new(expires_in: 1.minute, namespace: "myapp-cache")
# ```
def initialize(@expires_in : Time::Span, @cache = Redis::Client.new, @namespace : String? = nil)
end

def keys : Set(K)
def keys : Set(String)
pattern = namespace_key("*")
if namespace = @namespace
redis.keys(pattern).map(&.as(K).sub(namespace + ':', "")).to_set
redis.keys(pattern).map(&.as(String).sub(namespace + ':', "")).to_set
else
redis.keys(pattern).map(&.as(K)).to_set
redis.keys(pattern).map(&.as(String)).to_set
end
end

private def write_impl(key : K, value : V, *, expires_in = @expires_in)
private def write_impl(key : String, value : V, *, expires_in = @expires_in)
redis.set(key, value.to_s, ex: expires_in)
end

private def read_impl(key : K)
private def read_impl(key : String)
redis.get(key)
end

def delete_impl(key : K) : Bool
def delete_impl(key : String) : Bool
redis.del(key) == 1_i64
end

def exists_impl(key : K) : Bool
def exists_impl(key : String) : Bool
redis.exists(key) == 1
end

Expand All @@ -86,7 +86,7 @@ module Cache
# Increment a cached value. This method uses the Redis incr atomic operator.
#
# Calling it on a value not stored will initialize that value to zero.
def increment(key : K, amount = 1)
def increment(key : String, amount = 1)
key = namespace_key(key)

redis.incrby(key, amount).tap do
Expand All @@ -97,15 +97,15 @@ module Cache
# Decrement a cached value. This method uses the Redis decr atomic operator.
#
# Calling it on a value not stored will initialize that value to zero.
def decrement(key : K, amount = 1)
def decrement(key : String, amount = 1)
key = namespace_key(key)

redis.decrby(key, amount).tap do
write_key_expiry(key)
end
end

private def write_key_expiry(key : K)
private def write_key_expiry(key : String)
redis.expire(key, @expires_in.total_seconds.to_i)
end

Expand Down