package cache import ( "sync" "time" ) // MemoryCache is the in-memory cache. type MemoryCache struct { mu sync.Mutex duration time.Duration alerts map[string]*cachedAlert } type cachedAlert struct { expires time.Time status string } // NewMemoryCache creates a in-memory cache. func NewMemoryCache(d time.Duration) Cache { c := new(MemoryCache) c.duration = d c.alerts = make(map[string]*cachedAlert) return c } // Set saves an alert in the cache. func (c *MemoryCache) Set(fingerprint string, status string) error { c.mu.Lock() defer c.mu.Unlock() alert := new(cachedAlert) alert.expires = time.Now().Add(c.duration) alert.status = status c.alerts[fingerprint] = alert return nil } // Contains checks if an alert with a given fingerprint is in the cache // and if the status matches. func (c *MemoryCache) Contains(fingerprint string, status string) (bool, error) { c.mu.Lock() defer c.mu.Unlock() alert, ok := c.alerts[fingerprint] if ok { return alert.status == status, nil } return false, nil } func (a *cachedAlert) expired() bool { return a.expires.Before(time.Now()) } // Cleanup iterates over all alerts in the cache and removes them, if they // are expired. func (c *MemoryCache) Cleanup() { c.mu.Lock() defer c.mu.Unlock() for key, value := range c.alerts { if value.expired() { delete(c.alerts, key) } } }