2023-02-04 08:26:23 +01:00
|
|
|
package main
|
|
|
|
|
|
|
|
import (
|
|
|
|
"sync"
|
|
|
|
"time"
|
|
|
|
)
|
|
|
|
|
|
|
|
type fingerprint string
|
2023-02-08 20:30:56 +01:00
|
|
|
type status string
|
2023-02-04 08:26:23 +01:00
|
|
|
|
|
|
|
type cachedAlert struct {
|
|
|
|
expires time.Time
|
2023-02-08 20:30:56 +01:00
|
|
|
status status
|
2023-02-04 08:26:23 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
type cache struct {
|
2023-02-08 14:46:14 +01:00
|
|
|
mu sync.Mutex
|
|
|
|
duration time.Duration
|
|
|
|
alerts map[fingerprint]*cachedAlert
|
2023-02-04 08:26:23 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
func (a *cachedAlert) expired() bool {
|
|
|
|
return a.expires.Before(time.Now())
|
|
|
|
}
|
|
|
|
|
2023-02-08 14:46:14 +01:00
|
|
|
func newCache(d time.Duration) *cache {
|
2023-02-04 08:26:23 +01:00
|
|
|
c := new(cache)
|
2023-02-08 14:46:14 +01:00
|
|
|
c.duration = d
|
2023-02-04 08:26:23 +01:00
|
|
|
c.alerts = make(map[fingerprint]*cachedAlert)
|
|
|
|
|
|
|
|
return c
|
|
|
|
}
|
|
|
|
|
|
|
|
func (c *cache) cleanup() {
|
|
|
|
c.mu.Lock()
|
|
|
|
defer c.mu.Unlock()
|
|
|
|
for key, value := range c.alerts {
|
|
|
|
if value.expired() {
|
|
|
|
delete(c.alerts, key)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-02-08 20:30:56 +01:00
|
|
|
func (c *cache) set(f fingerprint, s status) {
|
2023-02-04 08:26:23 +01:00
|
|
|
c.mu.Lock()
|
|
|
|
defer c.mu.Unlock()
|
|
|
|
alert := new(cachedAlert)
|
2023-02-08 14:46:14 +01:00
|
|
|
alert.expires = time.Now().Add(c.duration)
|
2023-02-08 20:30:56 +01:00
|
|
|
alert.status = s
|
2023-02-04 08:26:23 +01:00
|
|
|
|
|
|
|
c.alerts[f] = alert
|
|
|
|
}
|
|
|
|
|
2023-02-08 20:30:56 +01:00
|
|
|
func (c *cache) contains(f fingerprint, s status) bool {
|
2023-02-04 08:26:23 +01:00
|
|
|
c.mu.Lock()
|
|
|
|
defer c.mu.Unlock()
|
2023-02-08 20:30:56 +01:00
|
|
|
alert, ok := c.alerts[f]
|
|
|
|
if ok {
|
|
|
|
return alert.status == s
|
|
|
|
}
|
|
|
|
|
|
|
|
return false
|
2023-02-04 08:26:23 +01:00
|
|
|
}
|