2023-03-08 22:05:15 +01:00
|
|
|
package cache
|
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
|
|
|
"time"
|
|
|
|
|
|
|
|
"github.com/redis/go-redis/v9"
|
|
|
|
)
|
|
|
|
|
2023-07-14 15:10:40 +02:00
|
|
|
const redisTimeout = 3 * time.Second
|
|
|
|
|
2023-03-08 22:05:15 +01:00
|
|
|
// 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)
|
2023-07-14 15:10:40 +02:00
|
|
|
ctx, cancel := context.WithTimeout(context.TODO(), redisTimeout)
|
|
|
|
defer cancel()
|
|
|
|
|
|
|
|
err = rdb.Ping(ctx).Err()
|
2023-07-10 12:20:16 +02:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
2023-03-08 22:05:15 +01:00
|
|
|
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 {
|
2023-07-14 15:10:40 +02:00
|
|
|
ctx, cancel := context.WithTimeout(context.TODO(), redisTimeout)
|
|
|
|
defer cancel()
|
|
|
|
|
|
|
|
return c.client.SetEx(ctx, fingerprint, status, c.duration).Err()
|
2023-03-08 22:05:15 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
// 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) {
|
2023-07-14 15:10:40 +02:00
|
|
|
ctx, cancel := context.WithTimeout(context.TODO(), redisTimeout)
|
|
|
|
defer cancel()
|
|
|
|
|
|
|
|
val, err := c.client.Get(ctx, fingerprint).Result()
|
2023-03-08 22:05:15 +01:00
|
|
|
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() {}
|