logs-analyzer/signoz/pkg/query-service/cache/redis/redis.go
2024-09-02 22:47:30 +03:00

127 lines
3.2 KiB
Go

package redis
import (
"context"
"fmt"
"time"
"github.com/go-redis/redis/v8"
"go.signoz.io/signoz/pkg/query-service/cache/status"
"go.uber.org/zap"
)
type cache struct {
client *redis.Client
opts *Options
}
// New creates a new cache
func New(opts *Options) *cache {
if opts == nil {
opts = defaultOptions()
}
return &cache{opts: opts}
}
// WithClient creates a new cache with the given client
func WithClient(client *redis.Client) *cache {
return &cache{client: client}
}
// Connect connects to the redis server
func (c *cache) Connect() error {
c.client = redis.NewClient(&redis.Options{
Addr: fmt.Sprintf("%s:%d", c.opts.Host, c.opts.Port),
Password: c.opts.Password,
DB: c.opts.DB,
})
return nil
}
// Store stores the data in the cache
func (c *cache) Store(cacheKey string, data []byte, ttl time.Duration) error {
return c.client.Set(context.Background(), cacheKey, data, ttl).Err()
}
// Retrieve retrieves the data from the cache
func (c *cache) Retrieve(cacheKey string, allowExpired bool) ([]byte, status.RetrieveStatus, error) {
data, err := c.client.Get(context.Background(), cacheKey).Bytes()
if err != nil {
if err == redis.Nil {
return nil, status.RetrieveStatusKeyMiss, nil
}
return nil, status.RetrieveStatusError, err
}
return data, status.RetrieveStatusHit, nil
}
// SetTTL sets the TTL for the cache entry
func (c *cache) SetTTL(cacheKey string, ttl time.Duration) {
err := c.client.Expire(context.Background(), cacheKey, ttl).Err()
if err != nil {
zap.L().Error("error setting TTL for cache key", zap.String("cacheKey", cacheKey), zap.Duration("ttl", ttl), zap.Error(err))
}
}
// Remove removes the cache entry
func (c *cache) Remove(cacheKey string) {
err := c.client.Del(context.Background(), cacheKey).Err()
if err != nil {
zap.L().Error("error deleting cache key", zap.String("cacheKey", cacheKey), zap.Error(err))
}
}
// BulkRemove removes the cache entries
func (c *cache) BulkRemove(cacheKeys []string) {
for _, cacheKey := range cacheKeys {
c.Remove(cacheKey)
}
}
// Close closes the connection to the redis server
func (c *cache) Close() error {
return c.client.Close()
}
// Ping pings the redis server
func (c *cache) Ping() error {
return c.client.Ping(context.Background()).Err()
}
// GetClient returns the redis client
func (c *cache) GetClient() *redis.Client {
return c.client
}
// GetOptions returns the options
func (c *cache) GetOptions() *Options {
return c.opts
}
// GetTTL returns the TTL for the cache entry
func (c *cache) GetTTL(cacheKey string) time.Duration {
ttl, err := c.client.TTL(context.Background(), cacheKey).Result()
if err != nil {
zap.L().Error("error getting TTL for cache key", zap.String("cacheKey", cacheKey), zap.Error(err))
}
return ttl
}
// GetKeys returns the keys matching the pattern
func (c *cache) GetKeys(pattern string) ([]string, error) {
return c.client.Keys(context.Background(), pattern).Result()
}
// GetKeysWithTTL returns the keys matching the pattern with their TTL
func (c *cache) GetKeysWithTTL(pattern string) (map[string]time.Duration, error) {
keys, err := c.GetKeys(pattern)
if err != nil {
return nil, err
}
result := make(map[string]time.Duration)
for _, key := range keys {
result[key] = c.GetTTL(key)
}
return result, nil
}