Deployment
Automated deployment update
4b1daed
Raw
History Blame Contribute Delete
2.2 kB
// Package cache provides caching for the API Gateway.
package cache
import (
"context"
"crypto/sha256"
"encoding/hex"
"encoding/json"
"time"
"github.com/redis/go-redis/v9"
"go.uber.org/zap"
)
// Config for cache manager
type Config struct {
RedisAddr string
RedisPassword string
RedisDB int
DefaultTTL time.Duration
MaxEntrySize int
KeyPrefix string
}
// Manager handles caching operations
type Manager struct {
client *redis.Client
config Config
logger *zap.Logger
}
// NewManager creates a cache manager
func NewManager(cfg Config, logger *zap.Logger) (*Manager, error) {
client := redis.NewClient(&redis.Options{
Addr: cfg.RedisAddr,
Password: cfg.RedisPassword,
DB: cfg.RedisDB,
})
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
if err := client.Ping(ctx).Err(); err != nil {
return nil, err
}
return &Manager{
client: client,
config: cfg,
logger: logger,
}, nil
}
// GenerateKey creates cache key from request
func (m *Manager) GenerateKey(parts ...string) string {
h := sha256.New()
for _, p := range parts {
h.Write([]byte(p))
}
return m.config.KeyPrefix + hex.EncodeToString(h.Sum(nil))
}
// Get retrieves cached value
func (m *Manager) Get(ctx context.Context, key string) (interface{}, bool) {
data, err := m.client.Get(ctx, key).Bytes()
if err != nil {
return nil, false
}
var result interface{}
if err := json.Unmarshal(data, &result); err != nil {
return nil, false
}
return result, true
}
// Set stores value in cache
func (m *Manager) Set(ctx context.Context, key string, value interface{}, ttl time.Duration) error {
data, err := json.Marshal(value)
if err != nil {
return err
}
if len(data) > m.config.MaxEntrySize {
m.logger.Warn("Cache entry exceeds max size", zap.String("key", key))
return nil
}
if ttl == 0 {
ttl = m.config.DefaultTTL
}
return m.client.Set(ctx, key, data, ttl).Err()
}
// Delete removes value from cache
func (m *Manager) Delete(ctx context.Context, key string) error {
return m.client.Del(ctx, key).Err()
}
// Close closes Redis connection
func (m *Manager) Close() error {
return m.client.Close()
}