Skip to content

Commit

Permalink
Merge pull request #52 from kumparan/feature/add-StoreCaches
Browse files Browse the repository at this point in the history
feature: add StoreCaches
  • Loading branch information
atjhoendz authored May 16, 2023
2 parents a2cfaa8 + 82682f2 commit cf26e71
Show file tree
Hide file tree
Showing 2 changed files with 110 additions and 0 deletions.
33 changes: 33 additions & 0 deletions common.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ import (
"fmt"
"strconv"

"github.com/kumparan/go-utils"
"github.com/sirupsen/logrus"

redigo "github.com/gomodule/redigo/redis"
"github.com/kumparan/redsync/v4"
)
Expand Down Expand Up @@ -132,3 +135,33 @@ func getHashMember(client redigo.Conn, identifier, key string) (value any, err e

return res[1], nil
}

// StoreCaches store multiple object by keys
func StoreCaches[K comparable, V any](cacheKeeper Keeper, keys []K, buffer map[K]V, cacheKeyFunc func(K) string) {
logger := logrus.WithFields(logrus.Fields{
"keys": keys,
"buffer": utils.Dump(buffer),
})

var cacheItems []Item
for _, key := range keys {
val, ok := buffer[key]
if !ok {
cacheItems = append(cacheItems, NewItem(cacheKeyFunc(key), []byte("null")))
continue
}

jsonVal, err := json.Marshal(val)
if err != nil {
logger.WithField("key", key).Error(err)
continue
}

cacheItems = append(cacheItems, NewItem(cacheKeyFunc(key), jsonVal))
}

err := cacheKeeper.StoreMultiWithoutBlocking(cacheItems)
if err != nil {
logger.WithField("cacheItems", utils.Dump(cacheItems)).Error(err)
}
}
77 changes: 77 additions & 0 deletions common_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@ package cacher
import (
"fmt"
"testing"
"time"

"github.com/alicebob/miniredis/v2"

"github.com/kumparan/go-utils"

Expand Down Expand Up @@ -57,3 +60,77 @@ func Test_ParseCacheResultToPointerObject(t *testing.T) {
assert.Equal(t, "failed to unmarshal [1,2,3,4,5,6] to *cacher.TestObj", err.Error())
})
}

func testCacheKey(key int64) string {
return fmt.Sprintf("cacheKey:%d", key)
}

func TestStoreMapValues(t *testing.T) {
k := NewKeeper()

m, err := miniredis.Run()
assert.NoError(t, err)

r := newRedisConn(m.Addr())
k.SetConnectionPool(r)
k.SetLockConnectionPool(r)
k.SetWaitTime(1 * time.Second)

type TestObj struct {
ID int64
}

t.Run("success", func(t *testing.T) {
keys := []int64{1, 2, 3}
buffer := make(map[int64]*TestObj)

for _, key := range keys {
buffer[key] = &TestObj{ID: key}
}

StoreCaches[int64, *TestObj](k, keys, buffer, testCacheKey)

for _, key := range keys {
assert.True(t, m.Exists(testCacheKey(key)))
redisVal, err := k.Get(testCacheKey(key))
assert.NoError(t, err)
res, err := ParseCacheResultToPointerObject[TestObj](redisVal)
assert.NoError(t, err)
assert.NotNil(t, res)
assert.Equal(t, TestObj{ID: key}, *res)
}
})

t.Run("success, some keys not exist in buffer", func(t *testing.T) {
keys := []int64{4, 5, 6}
buffer := make(map[int64]*TestObj)

for _, key := range keys {
buffer[key] = &TestObj{ID: key}
}

testKeys := []int64{4, 7, 8}

StoreCaches[int64, *TestObj](k, []int64{4, 7, 8}, buffer, testCacheKey)

for _, key := range testKeys {
if key == 4 {
assert.True(t, m.Exists(testCacheKey(key)))
redisVal, err := k.Get(testCacheKey(key))
assert.NoError(t, err)
res, err := ParseCacheResultToPointerObject[TestObj](redisVal)
assert.NoError(t, err)
assert.NotNil(t, res)
assert.Equal(t, TestObj{ID: 4}, *res)
continue
}

assert.True(t, m.Exists(testCacheKey(key)))
redisVal, err := k.Get(testCacheKey(key))
assert.NoError(t, err)
res, err := ParseCacheResultToPointerObject[TestObj](redisVal)
assert.NoError(t, err)
assert.Nil(t, res)
}
})
}

0 comments on commit cf26e71

Please sign in to comment.