Spaces:
Build error
Build error
| // 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() | |
| } | |