Go Test
This commit is contained in:
@@ -0,0 +1,44 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
type Cache struct {
|
||||
mu sync.RWMutex
|
||||
items map[string]cacheItem
|
||||
}
|
||||
|
||||
type cacheItem struct {
|
||||
value any
|
||||
expiresAt time.Time
|
||||
}
|
||||
|
||||
func NewCache() *Cache {
|
||||
return &Cache{items: make(map[string]cacheItem)}
|
||||
}
|
||||
|
||||
func GetOrLoad[T any](cache *Cache, key string, ttl time.Duration, loader func() (T, error)) (T, error) {
|
||||
var zero T
|
||||
|
||||
cache.mu.RLock()
|
||||
item, ok := cache.items[key]
|
||||
cache.mu.RUnlock()
|
||||
if ok && (item.expiresAt.IsZero() || item.expiresAt.After(time.Now())) {
|
||||
if value, castOK := item.value.(T); castOK {
|
||||
return value, nil
|
||||
}
|
||||
}
|
||||
|
||||
value, err := loader()
|
||||
if err != nil {
|
||||
return zero, err
|
||||
}
|
||||
|
||||
cache.mu.Lock()
|
||||
cache.items[key] = cacheItem{value: value, expiresAt: time.Now().Add(ttl)}
|
||||
cache.mu.Unlock()
|
||||
|
||||
return value, nil
|
||||
}
|
||||
Reference in New Issue
Block a user