teldrive/internal/cache/cache.go

101 lines
1.7 KiB
Go
Raw Normal View History

2023-11-02 21:51:30 +08:00
package cache
import (
"context"
2023-11-02 21:51:30 +08:00
"sync"
"time"
2023-11-02 21:51:30 +08:00
"github.com/coocood/freecache"
"github.com/gin-gonic/gin"
"github.com/vmihailenco/msgpack"
2023-11-02 21:51:30 +08:00
)
type Cache struct {
cache *freecache.Cache
mu sync.RWMutex
}
func (c *Cache) Get(key string, value interface{}) error {
c.mu.RLock()
defer c.mu.RUnlock()
result, err := c.cache.Get([]byte(key))
if err != nil {
return err
}
2023-11-02 21:51:30 +08:00
err = msgpack.Unmarshal(result, value)
2023-11-02 21:51:30 +08:00
if err != nil {
return err
}
return nil
2023-11-02 21:51:30 +08:00
}
func (c *Cache) Set(key string, value interface{}, expires time.Duration) error {
2023-11-02 21:51:30 +08:00
c.mu.Lock()
defer c.mu.Unlock()
bytes, err := msgpack.Marshal(value)
2023-11-02 21:51:30 +08:00
if err != nil {
return err
}
return c.cache.Set([]byte(key), bytes, int(expires.Seconds()))
2023-11-02 21:51:30 +08:00
}
func (c *Cache) Delete(key string) error {
c.mu.Lock()
defer c.mu.Unlock()
c.cache.Del([]byte(key))
2023-11-02 21:51:30 +08:00
return nil
}
var (
defaultCache *Cache
defaultCacheOnce sync.Once
)
type Config struct {
Size int
}
var conf = &Config{
Size: 5 * 1024 * 1024,
}
func SetConfig(c *Config) {
conf = &Config{
Size: c.Size,
}
}
func DefaultCache() *Cache {
defaultCacheOnce.Do(func() {
defaultCache = &Cache{cache: freecache.NewCache(conf.Size)}
})
return defaultCache
}
type cacheKeyType string
var contextKey = cacheKeyType("cache")
func WithCache(ctx context.Context, cache *Cache) context.Context {
if gCtx, ok := ctx.(*gin.Context); ok {
ctx = gCtx.Request.Context()
}
return context.WithValue(ctx, contextKey, cache)
}
func FromContext(ctx context.Context) *Cache {
if ctx == nil {
return DefaultCache()
}
if gCtx, ok := ctx.(*gin.Context); ok && gCtx != nil {
ctx = gCtx.Request.Context()
}
if cache, ok := ctx.Value(contextKey).(*Cache); ok {
return cache
}
return DefaultCache()
}