Skip to content
Snippets Groups Projects
Commit bc822896 authored by ensiouel's avatar ensiouel
Browse files

refactor: добавлен интерфейс для кэша

parent 0625050f
No related branches found
No related tags found
No related merge requests found
package cache
import (
"fmt"
"time"
"git.perx.ru/perxis/perxis-go/pkg/service"
lru "github.com/hashicorp/golang-lru/v2"
"go.uber.org/zap"
)
const (
defaultCacheSize = 1000
defaultTTL = 30 * time.Second
)
type Cache interface {
Set(key, value any) error
Get(key any) (any, error)
Remove(key any) error
}
var _ Cache = &MemoryCache{}
type MemoryCache struct {
cache *lru.Cache[interface{}, interface{}]
ttl time.Duration
logger *zap.Logger
}
type item struct {
value interface{}
expiredAt time.Time
}
func NewCache(size int, ttl time.Duration, opts ...interface{}) *MemoryCache {
if size == 0 {
size = defaultCacheSize
}
if ttl == 0 {
ttl = defaultTTL
}
c, err := lru.New[interface{}, interface{}](size)
if err != nil {
panic(err)
}
ch := &MemoryCache{
cache: c,
ttl: ttl,
logger: zap.NewNop(),
}
for _, o := range opts {
switch p := o.(type) {
case *zap.Logger:
ch.logger = p
}
}
ch.logger = ch.logger.Named("Cache")
return ch
}
func (c *MemoryCache) Set(key, value interface{}) (err error) {
c.cache.Add(key, &item{value: value, expiredAt: time.Now().Add(c.ttl)})
c.logger.Debug("Set", zap.String("key", fmt.Sprintf("%v", key)), zap.String("ptr", fmt.Sprintf("%p", value)))
return nil
}
func (c *MemoryCache) Get(key interface{}) (value interface{}, err error) {
val, ok := c.cache.Get(key)
if ok {
v := val.(*item)
if v.expiredAt.Before(time.Now()) {
_ = c.Remove(key)
c.logger.Debug("Expired", zap.String("key", fmt.Sprintf("%v", key)), zap.String("ptr", fmt.Sprintf("%p", v.value)))
return nil, service.ErrNotFound
}
c.logger.Debug("Hit", zap.String("key", fmt.Sprintf("%v", key)), zap.String("ptr", fmt.Sprintf("%p", v.value)))
return v.value, nil
}
c.logger.Debug("Miss", zap.String("key", fmt.Sprintf("%v", key)))
return nil, service.ErrNotFound
}
func (c *MemoryCache) Remove(key interface{}) (err error) {
present := c.cache.Remove(key)
c.logger.Debug("Remove", zap.String("key", fmt.Sprintf("%v", key)))
if !present {
err = service.ErrNotFound
}
return
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment