Skip to content

Commit

Permalink
Merge pull request #4 from ramadani/redis-universal-client
Browse files Browse the repository at this point in the history
Redis universal client
  • Loading branch information
ramadani authored Aug 11, 2021
2 parents ec4d05d + 5f33e0c commit 56d6a6b
Show file tree
Hide file tree
Showing 6 changed files with 246 additions and 4 deletions.
24 changes: 22 additions & 2 deletions cache/cache_redis_cluster.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,11 +36,31 @@ func (c *cacheRedisCluster) SetNX(ctx context.Context, key string, value interfa
}

func (c *cacheRedisCluster) Exists(ctx context.Context, keys ...string) (int64, error) {
return c.client.Exists(ctx, keys...).Result()
n := int64(0)

for _, key := range keys {
i, err := c.client.Exists(ctx, key).Result()
if err != nil {
return 0, err
}
n += i
}

return n, nil
}

func (c *cacheRedisCluster) Del(ctx context.Context, keys ...string) (int64, error) {
return c.client.Del(ctx, keys...).Result()
n := int64(0)

for _, key := range keys {
i, err := c.client.Del(ctx, key).Result()
if err != nil {
return 0, err
}
n += i
}

return n, nil
}

// NewCacheRedisCluster cache using redis cluster
Expand Down
41 changes: 41 additions & 0 deletions cache/cache_redis_cluster_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,29 @@ func TestCacheRedisCluster(t *testing.T) {
assert.Nil(t, err)
})

t.Run("ExistsHasError", func(t *testing.T) {
defer miniRedis.SetError("")

key := "123-5-1"
ttl := 5 * time.Second

res, err := redisCache.Set(ctx, key, "1", ttl)

assert.Equal(t, "OK", res)
assert.Nil(t, err)

exists, err := redisCache.Exists(ctx, fmt.Sprintf("test-%s", key))

assert.Equal(t, int64(0), exists)
assert.Nil(t, err)

miniRedis.SetError("error")
exists, err = redisCache.Exists(ctx, key)

assert.Equal(t, int64(0), exists)
assert.Error(t, err)
})

t.Run("Delete", func(t *testing.T) {
key := "123-6"
ttl := 5 * time.Second
Expand All @@ -110,4 +133,22 @@ func TestCacheRedisCluster(t *testing.T) {
assert.Equal(t, int64(0), exists)
assert.Nil(t, err)
})

t.Run("DeleteHasError", func(t *testing.T) {
defer miniRedis.SetError("")

key := "123-6-1"
ttl := 5 * time.Second

res, err := redisCache.Set(ctx, key, "1", ttl)

assert.Equal(t, "OK", res)
assert.Nil(t, err)

miniRedis.SetError("error")
exists, err := redisCache.Del(ctx, key)

assert.Equal(t, int64(0), exists)
assert.Error(t, err)
})
}
49 changes: 49 additions & 0 deletions cache/cache_redis_universal.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package cache

import (
"context"
"github.com/go-redis/redis/v8"
"github.com/ramadani/andromeda"
"time"
)

type cacheRedisUniversal struct {
client redis.UniversalClient
}

func (c *cacheRedisUniversal) IncrBy(ctx context.Context, key string, value int64) (int64, error) {
return c.client.IncrBy(ctx, key, value).Result()
}

func (c *cacheRedisUniversal) DecrBy(ctx context.Context, key string, decrement int64) (int64, error) {
return c.client.DecrBy(ctx, key, decrement).Result()
}

func (c *cacheRedisUniversal) Set(ctx context.Context, key string, value interface{}, expiration time.Duration) (string, error) {
return c.client.Set(ctx, key, value, expiration).Result()
}

func (c *cacheRedisUniversal) Get(ctx context.Context, key string) (string, error) {
val, err := c.client.Get(ctx, key).Result()
if err == redis.Nil {
err = andromeda.ErrCacheNotFound
}
return val, err
}

func (c *cacheRedisUniversal) SetNX(ctx context.Context, key string, value interface{}, expiration time.Duration) (bool, error) {
return c.client.SetNX(ctx, key, value, expiration).Result()
}

func (c *cacheRedisUniversal) Exists(ctx context.Context, keys ...string) (int64, error) {
return c.client.Exists(ctx, keys...).Result()
}

func (c *cacheRedisUniversal) Del(ctx context.Context, keys ...string) (int64, error) {
return c.client.Del(ctx, keys...).Result()
}

// NewCacheRedisUniversal cache using redis
func NewCacheRedisUniversal(client redis.UniversalClient) andromeda.Cache {
return &cacheRedisUniversal{client: client}
}
115 changes: 115 additions & 0 deletions cache/cache_redis_universal_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
package cache_test

import (
"context"
"fmt"
"github.com/alicebob/miniredis/v2"
"github.com/go-redis/redis/v8"
"github.com/ramadani/andromeda"
"github.com/ramadani/andromeda/cache"
"github.com/stretchr/testify/assert"
"testing"
"time"
)

func TestCacheRedisUniversal(t *testing.T) {
ctx := context.TODO()
miniRedis, err := miniredis.Run()
assert.Nil(t, err)

redisCache := cache.NewCacheRedisUniversal(redis.NewUniversalClient(&redis.UniversalOptions{
Addrs: []string{miniRedis.Addr()},
}))

t.Run("IncrByAndDecrBy", func(t *testing.T) {
key := "123-1"

res, err := redisCache.IncrBy(ctx, key, 1)

assert.Equal(t, int64(1), res)
assert.Nil(t, err)

res, err = redisCache.DecrBy(ctx, key, 1)

assert.Equal(t, int64(0), res)
assert.Nil(t, err)
})

t.Run("SetAndGet", func(t *testing.T) {
key := "123-2"
ttl := 5 * time.Second

res, err := redisCache.Set(ctx, key, "1", ttl)

assert.Equal(t, "OK", res)
assert.Nil(t, err)

res, err = redisCache.Get(ctx, key)

assert.Equal(t, "1", res)
assert.Nil(t, err)
})

t.Run("ErrCacheNotFound", func(t *testing.T) {
key := "123-3"
res, err := redisCache.Get(ctx, key)

assert.Equal(t, "", res)
assert.Equal(t, andromeda.ErrCacheNotFound, err)
})

t.Run("SetNX", func(t *testing.T) {
key := "123-4"
ttl := 5 * time.Second

res, err := redisCache.SetNX(ctx, key, "1", ttl)

assert.True(t, res)
assert.Nil(t, err)

res, err = redisCache.SetNX(ctx, key, "1", ttl)

assert.False(t, res)
assert.Nil(t, err)
})

t.Run("Exists", func(t *testing.T) {
key := "123-5"
ttl := 5 * time.Second

res, err := redisCache.Set(ctx, key, "1", ttl)

assert.Equal(t, "OK", res)
assert.Nil(t, err)

exists, err := redisCache.Exists(ctx, key)

assert.Equal(t, int64(1), exists)
assert.Nil(t, err)

exists, err = redisCache.Exists(ctx, fmt.Sprintf("test-%s", key))

assert.Equal(t, int64(0), exists)
assert.Nil(t, err)
})

t.Run("Delete", func(t *testing.T) {
key := "123-6"
ttl := 5 * time.Second

res, err := redisCache.Set(ctx, key, "1", ttl)

assert.Equal(t, "OK", res)
assert.Nil(t, err)

exists, err := redisCache.Del(ctx, key)

assert.Equal(t, int64(1), exists)
assert.Nil(t, err)

exists, err = redisCache.Del(ctx, key)

assert.Equal(t, int64(0), exists)
assert.Nil(t, err)
})
}
6 changes: 4 additions & 2 deletions get_cached_quota.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,10 @@ func (q *getCachedQuota) Do(ctx context.Context, req *QuotaRequest) (int64, erro
return 0, err
}

res, _ := strconv.Atoi(val)

res, err := strconv.Atoi(val)
if err != nil {
return 0, err
}
return int64(res), nil
}

Expand Down
15 changes: 15 additions & 0 deletions get_cached_quota_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,4 +77,19 @@ func TestGetCachedQuota(t *testing.T) {
assert.Equal(t, int64(1000), res)
assert.Nil(t, err)
})

t.Run("ErrorConvertValue", func(t *testing.T) {
defer mockCtrl.Finish()

req := &andromeda.QuotaRequest{QuotaID: "123"}
key := "123-key"

mockGetQuotaKey.EXPECT().Do(ctx, req).Return(key, nil)
mockCache.EXPECT().Get(ctx, key).Return("lorem", nil)

res, err := getCachedQuota.Do(ctx, req)

assert.Equal(t, int64(0), res)
assert.NotNil(t, err)
})
}

0 comments on commit 56d6a6b

Please sign in to comment.