package cache import ( "context" "time" "github.com/redis/go-redis/v9" ) const redisTimeout = 3 * time.Second // RedisCache is the redis cache. type RedisCache struct { client *redis.Client duration time.Duration } // NewRedisCache creates a new redis cache/client. func NewRedisCache(redisURL string, d time.Duration) (Cache, error) { c := new(RedisCache) ropts, err := redis.ParseURL(redisURL) if err != nil { return nil, err } rdb := redis.NewClient(ropts) ctx, cancel := context.WithTimeout(context.TODO(), redisTimeout) defer cancel() err = rdb.Ping(ctx).Err() if err != nil { return nil, err } c.client = rdb c.duration = d return c, nil } // Set saves an alert in the cache. func (c *RedisCache) Set(fingerprint string, status string) error { ctx, cancel := context.WithTimeout(context.TODO(), redisTimeout) defer cancel() return c.client.SetEx(ctx, fingerprint, status, c.duration).Err() } // Contains checks if an alert with a given fingerprint is in the cache // and if the status matches. func (c *RedisCache) Contains(fingerprint string, status string) (bool, error) { ctx, cancel := context.WithTimeout(context.TODO(), redisTimeout) defer cancel() val, err := c.client.Get(ctx, fingerprint).Result() if err == redis.Nil { return false, nil } else if err != nil { return false, err } return val == status, nil } // Cleanup is an empty function that is simply here to implement the interface. // Redis does its own cleanup. func (c *RedisCache) Cleanup() {}