-
-
Notifications
You must be signed in to change notification settings - Fork 201
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Loadable and Expiration #101
Comments
I also need to be able to set both the TTL and tag for specific loadable |
Easy enough to make my own copy: package cache
import (
"context"
"sync"
"github.com/eko/gocache/v3/cache"
"github.com/eko/gocache/v3/store"
)
const (
// LoadableType represents the loadable cache type as a string value
LoadableType = "loadable"
)
type loadableKeyValue[T any] struct {
key any
value T
options []store.Option
}
type LoadFunction[T any] func(ctx context.Context, key any) (T, []store.Option, error)
// LoadableCache represents a cache that uses a function to load data
type LoadableCache[T any] struct {
loadFunc LoadFunction[T]
cache cache.CacheInterface[T]
setChannel chan *loadableKeyValue[T]
setterWg *sync.WaitGroup
}
// NewLoadable instanciates a new cache that uses a function to load data
func NewLoadable[T any](loadFunc LoadFunction[T], cache cache.CacheInterface[T]) *LoadableCache[T] {
loadable := &LoadableCache[T]{
loadFunc: loadFunc,
cache: cache,
setChannel: make(chan *loadableKeyValue[T], 10000),
setterWg: &sync.WaitGroup{},
}
loadable.setterWg.Add(1)
go loadable.setter()
return loadable
}
func (c *LoadableCache[T]) setter() {
defer c.setterWg.Done()
for item := range c.setChannel {
c.Set(context.Background(), item.key, item.value, item.options...)
}
}
// Get returns the object stored in cache if it exists
func (c *LoadableCache[T]) Get(ctx context.Context, key any) (T, error) {
var err error
object, err := c.cache.Get(ctx, key)
if err == nil {
return object, err
}
// Unable to find in cache, try to load it from load function
object, options, err := c.loadFunc(ctx, key)
if err != nil {
return object, err
}
// Then, put it back in cache
c.setChannel <- &loadableKeyValue[T]{key, object, options}
return object, err
}
// Set sets a value in available caches
func (c *LoadableCache[T]) Set(ctx context.Context, key any, object T, options ...store.Option) error {
return c.cache.Set(ctx, key, object, options...)
}
// Delete removes a value from cache
func (c *LoadableCache[T]) Delete(ctx context.Context, key any) error {
return c.cache.Delete(ctx, key)
}
// Invalidate invalidates cache item from given options
func (c *LoadableCache[T]) Invalidate(ctx context.Context, options ...store.InvalidateOption) error {
return c.cache.Invalidate(ctx, options...)
}
// Clear resets all cache data
func (c *LoadableCache[T]) Clear(ctx context.Context) error {
return c.cache.Clear(ctx)
}
// GetType returns the cache type
func (c *LoadableCache[T]) GetType() string {
return LoadableType
}
func (c *LoadableCache[T]) Close() error {
close(c.setChannel)
c.setterWg.Wait()
return nil
} |
Would be great if the load function supported an optional expiration |
it's a good idea to add |
@eko are there plans to merge @sgtsquiggs solution from #101 (comment)? It seems to resolve the issue of loadable not supporting expiration? i tested it and seems to work just fine. thank you so much |
Loadable cache: make options to be re-used in setter (fixes #101)
Hi, Thank you, this is done, options are now used in setters so TTLs should be respected. |
In the LoadFunction can i manage the key expiration somewhere?
The text was updated successfully, but these errors were encountered: