package utils import ( "sync" "time" ) // CacheItem represents a cached item with expiration type CacheItem struct { Value interface{} Expiration time.Time } // Cache represents a simple in-memory cache with expiration type Cache struct { mu sync.RWMutex items map[string]CacheItem } // NewCache creates a new cache instance func NewCache() *Cache { c := &Cache{ items: make(map[string]CacheItem), } // Start cleanup goroutine go c.cleanupExpired() return c } // Get retrieves a value from the cache func (c *Cache) Get(key string) interface{} { c.mu.RLock() defer c.mu.RUnlock() item, exists := c.items[key] if !exists { return nil } // Check if item has expired if time.Now().After(item.Expiration) { return nil } return item.Value } // Set stores a value in the cache with an expiration duration func (c *Cache) Set(key string, value interface{}, duration time.Duration) { c.mu.Lock() defer c.mu.Unlock() c.items[key] = CacheItem{ Value: value, Expiration: time.Now().Add(duration), } } // Delete removes a value from the cache func (c *Cache) Delete(key string) { c.mu.Lock() defer c.mu.Unlock() delete(c.items, key) } // Clear removes all items from the cache func (c *Cache) Clear() { c.mu.Lock() defer c.mu.Unlock() c.items = make(map[string]CacheItem) } // cleanupExpired periodically removes expired items func (c *Cache) cleanupExpired() { ticker := time.NewTicker(5 * time.Minute) defer ticker.Stop() for range ticker.C { c.mu.Lock() now := time.Now() for key, item := range c.items { if now.After(item.Expiration) { delete(c.items, key) } } c.mu.Unlock() } } // Global cache instance var GlobalCache = NewCache()