Skip to content

Commit

Permalink
fix: infinite recursion in memory cache
Browse files Browse the repository at this point in the history
  • Loading branch information
xuhaidong committed Sep 26, 2023
1 parent f8e9963 commit 38ed592
Show file tree
Hide file tree
Showing 3 changed files with 23 additions and 13 deletions.
24 changes: 17 additions & 7 deletions extensions/cachext/backend/memory/memory.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package memory

import (
"context"
"sync"
"time"

"github.com/spf13/viper"
Expand All @@ -10,7 +11,7 @@ import (
)

func init() {
if err := cachext.RegisteBackend("memory", func() cachext.CacheBackend { return &memoryBackend{} }); err != nil {
if err := cachext.RegisterBackend("memory", func() cachext.CacheBackend { return &memoryBackend{} }); err != nil {
panic("MemoryBackend Init error")
}
}
Expand All @@ -21,6 +22,7 @@ type memoryBackendNode struct {
}

type memoryBackend struct {
lock sync.Mutex
client map[string]*memoryBackendNode
}

Expand All @@ -47,6 +49,8 @@ func (m *memoryBackend) Get(ctx context.Context, key string) ([]byte, error) {
}

func (m *memoryBackend) Set(ctx context.Context, key string, value []byte, ttl time.Duration) error {
m.lock.Lock()
defer m.lock.Unlock()
node := &memoryBackendNode{Value: value, ExpiredAt: time.Now().Add(ttl)}
m.client[key] = node
return nil
Expand All @@ -70,16 +74,20 @@ func (m *memoryBackend) GetMany(ctx context.Context, keys []string) [][]byte {
}

func (m *memoryBackend) Delete(ctx context.Context, key string) bool {
exists := m.Exists(ctx, key)
delete(m.client, key)
return exists
m.lock.Lock()
defer m.lock.Unlock()
if _, ok := m.client[key]; ok {
delete(m.client, key)
return true
}
return false
}

func (m *memoryBackend) DeleteMany(ctx context.Context, keys []string) bool {
var res bool
res := true
for _, key := range keys {
if m.Delete(ctx, key) {
res = true
if !m.Delete(ctx, key) {
res = false
}
}
return res
Expand All @@ -90,6 +98,8 @@ func (m *memoryBackend) Expire(ctx context.Context, key string, ttl time.Duratio
if val == nil {
return false
}
m.lock.Lock()
defer m.lock.Unlock()
m.client[key].ExpiredAt = time.Now().Add(ttl)
return true
}
Expand Down
2 changes: 1 addition & 1 deletion extensions/cachext/backend/redis/redis.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import (
)

func init() {
if err := cachext.RegisteBackend("redis", func() cachext.CacheBackend { return &redisBackend{} }); err != nil {
if err := cachext.RegisterBackend("redis", func() cachext.CacheBackend { return &redisBackend{} }); err != nil {
panic("RedisBackend init error")
}
}
Expand Down
10 changes: 5 additions & 5 deletions extensions/cachext/ext.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,11 @@ import (
"sync"
"time"

"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promauto"
"github.com/shanbay/gobay"
"github.com/spf13/viper"
"github.com/vmihailenco/msgpack"
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promauto"
)

type void struct{}
Expand Down Expand Up @@ -119,16 +119,16 @@ func (c *CacheExt) CheckHealth(ctx context.Context) error {
return nil
}

// RegisteBackend if you want a new backend, use this func to registe your backend
// RegisterBackend if you want a new backend, use this func to registe your backend
// then load it by config
func RegisteBackend(configBackend string, backendFunc func() CacheBackend) error {
func RegisterBackend(configBackend string, backendFunc func() CacheBackend) error {
mu.Lock()
defer mu.Unlock()
if _, exist := backendMap[configBackend]; !exist {
backendMap[configBackend] = backendFunc
return nil
} else {
return errors.New("Backend already registered")
return errors.New("backend already registered")
}
}

Expand Down

0 comments on commit 38ed592

Please sign in to comment.