mirror of https://github.com/synctv-org/synctv
fix: refresh cache and delete movie cache
parent
cc6e63283d
commit
b8fa101412
@ -0,0 +1,172 @@
|
||||
package cache
|
||||
|
||||
import (
|
||||
"context"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/zijiren233/gencontainer/refreshcache0"
|
||||
"golang.org/x/exp/maps"
|
||||
)
|
||||
|
||||
type MapRefreshFunc0[T any] func(ctx context.Context, key string) (T, error)
|
||||
|
||||
type MapCache0[T any] struct {
|
||||
lock sync.RWMutex
|
||||
cache map[string]*refreshcache0.RefreshCache[T]
|
||||
refreshFunc MapRefreshFunc0[T]
|
||||
maxAge time.Duration
|
||||
}
|
||||
|
||||
func newMapCache0[T any](refreshFunc MapRefreshFunc0[T], maxAge time.Duration) *MapCache0[T] {
|
||||
return &MapCache0[T]{
|
||||
cache: make(map[string]*refreshcache0.RefreshCache[T]),
|
||||
refreshFunc: refreshFunc,
|
||||
maxAge: maxAge,
|
||||
}
|
||||
}
|
||||
|
||||
func (b *MapCache0[T]) Clear() {
|
||||
b.lock.Lock()
|
||||
defer b.lock.Unlock()
|
||||
b.clear()
|
||||
}
|
||||
|
||||
func (b *MapCache0[T]) clear() {
|
||||
maps.Clear(b.cache)
|
||||
}
|
||||
|
||||
func (b *MapCache0[T]) Delete(key string) {
|
||||
b.lock.Lock()
|
||||
defer b.lock.Unlock()
|
||||
delete(b.cache, key)
|
||||
}
|
||||
|
||||
func (b *MapCache0[T]) LoadOrStore(ctx context.Context, key string) (T, error) {
|
||||
b.lock.RLock()
|
||||
c, loaded := b.cache[key]
|
||||
if loaded {
|
||||
b.lock.RUnlock()
|
||||
return c.Get(ctx)
|
||||
}
|
||||
b.lock.RUnlock()
|
||||
b.lock.Lock()
|
||||
c, loaded = b.cache[key]
|
||||
if loaded {
|
||||
b.lock.Unlock()
|
||||
return c.Get(ctx)
|
||||
}
|
||||
c = refreshcache0.NewRefreshCache[T](func(ctx context.Context) (T, error) {
|
||||
return b.refreshFunc(ctx, key)
|
||||
}, b.maxAge)
|
||||
b.cache[key] = c
|
||||
b.lock.Unlock()
|
||||
return c.Get(ctx)
|
||||
}
|
||||
|
||||
func (b *MapCache0[T]) StoreOrRefresh(ctx context.Context, key string) (T, error) {
|
||||
b.lock.RLock()
|
||||
c, ok := b.cache[key]
|
||||
if ok {
|
||||
b.lock.RUnlock()
|
||||
return c.Refresh(ctx)
|
||||
}
|
||||
b.lock.RUnlock()
|
||||
b.lock.Lock()
|
||||
c, ok = b.cache[key]
|
||||
if ok {
|
||||
b.lock.Unlock()
|
||||
return c.Refresh(ctx)
|
||||
}
|
||||
c = refreshcache0.NewRefreshCache[T](func(ctx context.Context) (T, error) {
|
||||
return b.refreshFunc(ctx, key)
|
||||
}, b.maxAge)
|
||||
b.cache[key] = c
|
||||
b.lock.Unlock()
|
||||
return c.Refresh(ctx)
|
||||
}
|
||||
|
||||
func (b *MapCache0[T]) LoadCache(key string) (*refreshcache0.RefreshCache[T], bool) {
|
||||
b.lock.RLock()
|
||||
c, ok := b.cache[key]
|
||||
b.lock.RUnlock()
|
||||
return c, ok
|
||||
}
|
||||
|
||||
func (b *MapCache0[T]) LoadOrNewCache(key string) *refreshcache0.RefreshCache[T] {
|
||||
b.lock.RLock()
|
||||
c, ok := b.cache[key]
|
||||
if ok {
|
||||
b.lock.RUnlock()
|
||||
return c
|
||||
}
|
||||
b.lock.RUnlock()
|
||||
b.lock.Lock()
|
||||
c, ok = b.cache[key]
|
||||
if ok {
|
||||
b.lock.Unlock()
|
||||
return c
|
||||
}
|
||||
c = refreshcache0.NewRefreshCache[T](func(ctx context.Context) (T, error) {
|
||||
return b.refreshFunc(ctx, key)
|
||||
}, b.maxAge)
|
||||
b.cache[key] = c
|
||||
b.lock.Unlock()
|
||||
return c
|
||||
}
|
||||
|
||||
func (b *MapCache0[T]) LoadOrStoreWithDynamicFunc(ctx context.Context, key string, refreshFunc MapRefreshFunc0[T]) (T, error) {
|
||||
b.lock.RLock()
|
||||
c, loaded := b.cache[key]
|
||||
if loaded {
|
||||
b.lock.RUnlock()
|
||||
return c.Data().Get(ctx, func(ctx context.Context) (T, error) {
|
||||
return refreshFunc(ctx, key)
|
||||
})
|
||||
}
|
||||
b.lock.RUnlock()
|
||||
b.lock.Lock()
|
||||
c, loaded = b.cache[key]
|
||||
if loaded {
|
||||
b.lock.Unlock()
|
||||
return c.Data().Get(ctx, func(ctx context.Context) (T, error) {
|
||||
return refreshFunc(ctx, key)
|
||||
})
|
||||
}
|
||||
c = refreshcache0.NewRefreshCache[T](func(ctx context.Context) (T, error) {
|
||||
return b.refreshFunc(ctx, key)
|
||||
}, b.maxAge)
|
||||
b.cache[key] = c
|
||||
b.lock.Unlock()
|
||||
return c.Data().Get(ctx, func(ctx context.Context) (T, error) {
|
||||
return refreshFunc(ctx, key)
|
||||
})
|
||||
}
|
||||
|
||||
func (b *MapCache0[T]) StoreOrRefreshWithDynamicFunc(ctx context.Context, key string, refreshFunc MapRefreshFunc0[T]) (T, error) {
|
||||
b.lock.RLock()
|
||||
c, ok := b.cache[key]
|
||||
if ok {
|
||||
b.lock.RUnlock()
|
||||
return c.Data().Refresh(ctx, func(ctx context.Context) (T, error) {
|
||||
return refreshFunc(ctx, key)
|
||||
})
|
||||
}
|
||||
b.lock.RUnlock()
|
||||
b.lock.Lock()
|
||||
c, ok = b.cache[key]
|
||||
if ok {
|
||||
b.lock.Unlock()
|
||||
return c.Data().Refresh(ctx, func(ctx context.Context) (T, error) {
|
||||
return refreshFunc(ctx, key)
|
||||
})
|
||||
}
|
||||
c = refreshcache0.NewRefreshCache[T](func(ctx context.Context) (T, error) {
|
||||
return b.refreshFunc(ctx, key)
|
||||
}, b.maxAge)
|
||||
b.cache[key] = c
|
||||
b.lock.Unlock()
|
||||
return c.Data().Refresh(ctx, func(ctx context.Context) (T, error) {
|
||||
return refreshFunc(ctx, key)
|
||||
})
|
||||
}
|
Loading…
Reference in New Issue