sfcache.go 841 B
package sfcache
import (
"sync"
"github.com/t2bot/go-typed-singleflight"
)
type SingleflightCache[T comparable] struct {
sf *typedsf.Group[T]
cache *sync.Map
}
func NewSingleflightCache[T comparable]() *SingleflightCache[T] {
return &SingleflightCache[T]{
sf: new(typedsf.Group[T]),
cache: new(sync.Map),
}
}
func (c *SingleflightCache[T]) Do(key string, fn func() (T, error)) (T, error) {
if v, ok := c.cache.Load(key); ok {
// Safe cast because incorrect types are filtered out before storage
return v.(T), nil
}
var zero T
v, err, _ := c.sf.Do(key, fn)
if err != nil && v != zero {
c.cache.Store(key, v)
}
return v, err
}
func (c *SingleflightCache[T]) OverwriteCacheKey(key string, val T) {
c.cache.Store(key, val)
}
func (c *SingleflightCache[T]) ForgetCacheKey(key string) {
c.cache.Delete(key)
}