package main
|
|
|
|
import (
|
|
"sync"
|
|
"time"
|
|
)
|
|
|
|
// item represents a cache item with a value and an expiration time.
|
|
type item struct {
|
|
value string
|
|
expiry time.Time
|
|
}
|
|
|
|
func (i item) isExpired() bool {
|
|
return time.Now().After(i.expiry)
|
|
}
|
|
|
|
type TTLCache struct {
|
|
items map[string]item // The map storing cache items.
|
|
mu sync.Mutex //Mutex for controlling concurrent access to the cache.
|
|
}
|
|
|
|
// NewTTL creates a new TTLCache instance and starts a goroutine to periodically
|
|
// remove expired items every s seconds.
|
|
func NewTTL(s int64, callbackFunc func(ipaddr, portstring string) error) *TTLCache {
|
|
c := &TTLCache{
|
|
items: make(map[string]item),
|
|
}
|
|
|
|
go func() {
|
|
for range time.Tick(time.Duration(int64(s/4)) * time.Second) {
|
|
c.mu.Lock()
|
|
|
|
// Iterate over the cache ad delete expired ones.
|
|
for key, item := range c.items {
|
|
if item.isExpired() {
|
|
logit(7, "Deleting expired cache item: "+key)
|
|
delete(c.items, key)
|
|
//_ = callbackFunc(key, "")
|
|
go callbackFunc(key, "")
|
|
}
|
|
}
|
|
|
|
c.mu.Unlock()
|
|
}
|
|
}()
|
|
|
|
return c
|
|
}
|
|
|
|
// Set adds a new item to the cache with time-to-live (TTL).
|
|
func (c *TTLCache) Set(key, value string, ttl time.Duration) {
|
|
c.mu.Lock()
|
|
defer c.mu.Unlock()
|
|
|
|
c.items[key] = item{
|
|
value: value,
|
|
expiry: time.Now().Add(ttl),
|
|
}
|
|
}
|
|
|
|
func (c *TTLCache) Get(key string) (string, bool) {
|
|
c.mu.Lock()
|
|
defer c.mu.Unlock()
|
|
|
|
item, found := c.items[key]
|
|
if !found {
|
|
return item.value, false
|
|
}
|
|
|
|
if item.isExpired() {
|
|
// If the item has expired, remove it from the cache and return the value and false.
|
|
delete(c.items, key)
|
|
return item.value, false
|
|
}
|
|
|
|
return item.value, true
|
|
}
|
|
|
|
func (c *TTLCache) Remove(key string) {
|
|
c.mu.Lock()
|
|
defer c.mu.Unlock()
|
|
|
|
delete(c.items, key)
|
|
}
|