Files
moteva/server/internal/infrastructure/cache/store.go
T

90 lines
1.6 KiB
Go
Raw Normal View History

package cache
import (
"context"
"encoding/json"
"errors"
"sync"
"time"
)
var ErrUnsupportedDriver = errors.New("unsupported cache driver")
type Store interface {
Get(ctx context.Context, key string, target any) (bool, error)
Set(ctx context.Context, key string, value any, ttl time.Duration) error
Delete(ctx context.Context, key string) error
}
type memoryItem struct {
value []byte
expiresAt time.Time
}
type MemoryStore struct {
mu sync.RWMutex
items map[string]memoryItem
}
func NewMemoryStore() *MemoryStore {
return &MemoryStore{
items: make(map[string]memoryItem),
}
}
func (s *MemoryStore) Get(ctx context.Context, key string, target any) (bool, error) {
if err := ctx.Err(); err != nil {
return false, err
}
s.mu.RLock()
item, ok := s.items[key]
s.mu.RUnlock()
if !ok {
return false, nil
}
if !item.expiresAt.IsZero() && time.Now().After(item.expiresAt) {
s.mu.Lock()
delete(s.items, key)
s.mu.Unlock()
return false, nil
}
if err := json.Unmarshal(item.value, target); err != nil {
return false, err
}
return true, nil
}
func (s *MemoryStore) Set(ctx context.Context, key string, value any, ttl time.Duration) error {
if err := ctx.Err(); err != nil {
return err
}
data, err := json.Marshal(value)
if err != nil {
return err
}
var expiresAt time.Time
if ttl > 0 {
expiresAt = time.Now().Add(ttl)
}
s.mu.Lock()
s.items[key] = memoryItem{value: data, expiresAt: expiresAt}
s.mu.Unlock()
return nil
}
func (s *MemoryStore) Delete(ctx context.Context, key string) error {
if err := ctx.Err(); err != nil {
return err
}
s.mu.Lock()
delete(s.items, key)
s.mu.Unlock()
return nil
}