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) }