Files
garage-ui/pkg/utils/cache.go
T

96 lines
1.7 KiB
Go

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