Skip to content

Commit

Permalink
Merge pull request #2 from plbouchard/hset-tags
Browse files Browse the repository at this point in the history
Replaced the tags csv string by a hset
  • Loading branch information
plbouchard committed Jan 12, 2021
2 parents d3c26de + 203d229 commit 07cc0a0
Show file tree
Hide file tree
Showing 3 changed files with 70 additions and 41 deletions.
48 changes: 15 additions & 33 deletions store/redis.go
Expand Up @@ -2,7 +2,6 @@ package store

import (
"fmt"
"strings"
"time"

redis "github.com/go-redis/redis/v7"
Expand All @@ -11,8 +10,11 @@ import (
// RedisClientInterface represents a go-redis/redis client
type RedisClientInterface interface {
Get(key string) *redis.StringCmd
HGetAll(key string) *redis.StringStringMapCmd
TTL(key string) *redis.DurationCmd
Set(key string, value interface{}, expiration time.Duration) *redis.StatusCmd
Expire(key string, expiration time.Duration) *redis.BoolCmd
Set(key string, values interface{}, expiration time.Duration) *redis.StatusCmd
HSet(key string, values ...interface{}) *redis.IntCmd
Del(keys ...string) *redis.IntCmd
FlushAll() *redis.StatusCmd
}
Expand All @@ -22,6 +24,8 @@ const (
RedisType = "redis"
// RedisTagPattern represents the tag pattern to be used as a key in specified storage
RedisTagPattern = "gocache_tag_%s"
// RedisEmptyValue represents an empty value to be used in hsets when the content is not used
RedisEmptyValue = 0
)

// RedisStore is a store for Redis
Expand Down Expand Up @@ -82,37 +86,12 @@ func (s *RedisStore) Set(key interface{}, value interface{}, options *Options) e

func (s *RedisStore) setTags(key interface{}, tags []string) {
for _, tag := range tags {
var tagKey = fmt.Sprintf(RedisTagPattern, tag)
var cacheKeys = s.getCacheKeysForTag(tagKey)

var alreadyInserted = false
for _, cacheKey := range cacheKeys {
if cacheKey == key.(string) {
alreadyInserted = true
break
}
}

if !alreadyInserted {
cacheKeys = append(cacheKeys, key.(string))
}

s.Set(tagKey, strings.Join(cacheKeys, ","), &Options{
Expiration: 720 * time.Hour,
})
tagKey := fmt.Sprintf(RedisTagPattern, tag)
s.client.HSet(tagKey, key.(string), RedisEmptyValue)
s.client.Expire(tagKey, 720*time.Hour)
}
}

func (s *RedisStore) getCacheKeysForTag(tagKey string) []string {
var cacheKeys = []string{}
if result, err := s.Get(tagKey); err == nil && result != "" {
if str, ok := result.(string); ok {
cacheKeys = strings.Split(str, ",")
}
}
return cacheKeys
}

// Delete removes data from Redis for given key identifier
func (s *RedisStore) Delete(key interface{}) error {
_, err := s.client.Del(key.(string)).Result()
Expand All @@ -123,10 +102,13 @@ func (s *RedisStore) Delete(key interface{}) error {
func (s *RedisStore) Invalidate(options InvalidateOptions) error {
if tags := options.TagsValue(); len(tags) > 0 {
for _, tag := range tags {
var tagKey = fmt.Sprintf(RedisTagPattern, tag)
var cacheKeys = s.getCacheKeysForTag(tagKey)
tagKey := fmt.Sprintf(RedisTagPattern, tag)
cacheKeys, err := s.client.HGetAll(tagKey).Result()
if err != nil {
continue
}

for _, cacheKey := range cacheKeys {
for cacheKey := range cacheKeys {
s.Delete(cacheKey)
}

Expand Down
8 changes: 4 additions & 4 deletions store/redis_test.go
Expand Up @@ -105,8 +105,8 @@ func TestRedisSetWithTags(t *testing.T) {

client := mocksStore.NewMockRedisClientInterface(ctrl)
client.EXPECT().Set(cacheKey, cacheValue, time.Duration(0)).Return(&redis.StatusCmd{})
client.EXPECT().Get("gocache_tag_tag1").Return(&redis.StringCmd{})
client.EXPECT().Set("gocache_tag_tag1", "my-key", 720*time.Hour).Return(&redis.StatusCmd{})
client.EXPECT().HSet("gocache_tag_tag1", "my-key", 0).Return(&redis.IntCmd{})
client.EXPECT().Expire("gocache_tag_tag1", 720*time.Hour).Return(&redis.BoolCmd{})

store := NewRedis(client, nil)

Expand Down Expand Up @@ -145,10 +145,10 @@ func TestRedisInvalidate(t *testing.T) {
Tags: []string{"tag1"},
}

cacheKeys := &redis.StringCmd{}
cacheKeys := &redis.StringStringMapCmd{}

client := mocksStore.NewMockRedisClientInterface(ctrl)
client.EXPECT().Get("gocache_tag_tag1").Return(cacheKeys)
client.EXPECT().HGetAll("gocache_tag_tag1").Return(cacheKeys)
client.EXPECT().Del("gocache_tag_tag1").Return(&redis.IntCmd{})

store := NewRedis(client, nil)
Expand Down
55 changes: 51 additions & 4 deletions test/mocks/store/clients/redis_interface.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 07cc0a0

Please sign in to comment.