github.com/angenalZZZ/gofunc@v0.0.0-20210507121333-48ff1be3917b/data/cache/loadable.go (about) 1 package cache 2 3 import ( 4 "fmt" 5 "time" 6 7 "github.com/angenalZZZ/gofunc/data/cache/store" 8 ) 9 10 const ( 11 // LoadableType represents the loadable cache type as a string value 12 LoadableType = "loadable" 13 ) 14 15 type loadableKeyValue struct { 16 key string 17 value interface{} 18 } 19 20 type loadFunction func(key interface{}) (interface{}, error) 21 22 // LoadableCache represents a cache that uses a function to load data 23 type LoadableCache struct { 24 loadFunc loadFunction 25 cache Interface 26 setChannel chan *loadableKeyValue 27 } 28 29 // NewLoadable create a new cache that uses a function to load data 30 func NewLoadable(loadFunc loadFunction, cache Interface) *LoadableCache { 31 loadable := &LoadableCache{ 32 loadFunc: loadFunc, 33 cache: cache, 34 setChannel: make(chan *loadableKeyValue, 10000), 35 } 36 37 go loadable.setter() 38 39 return loadable 40 } 41 42 func (c *LoadableCache) setter() { 43 for item := range c.setChannel { 44 _ = c.Set(item.key, item.value, nil) 45 } 46 } 47 48 // Get returns the object stored in cache if it exists 49 func (c *LoadableCache) Get(key string) (object interface{}, err error) { 50 object, err = c.cache.Get(key) 51 if err == nil { 52 return 53 } 54 55 // Unable to find in cache, try to load it from load function 56 object, err = c.loadFunc(key) 57 if err != nil { 58 _ = fmt.Errorf("An error has occurred while trying to load item from load function: %v\n", err) 59 return 60 } 61 62 // Then, put it back in cache 63 c.setChannel <- &loadableKeyValue{key, object} 64 return 65 } 66 67 // Set sets a value in available caches 68 func (c *LoadableCache) Set(key string, object interface{}, options *store.Options) error { 69 return c.cache.Set(key, object, options) 70 } 71 72 // TTL returns an expiration time 73 func (c *LoadableCache) TTL(key string) (time.Duration, error) { 74 return c.cache.TTL(key) 75 } 76 77 // Delete removes a value from cache 78 func (c *LoadableCache) Delete(key string) error { 79 return c.cache.Delete(key) 80 } 81 82 // Invalidate invalidates cache item from given options 83 func (c *LoadableCache) Invalidate(options store.InvalidateOptions) error { 84 return c.cache.Invalidate(options) 85 } 86 87 // Clear resets all cache data 88 func (c *LoadableCache) Clear() error { 89 return c.cache.Clear() 90 } 91 92 // GetType returns the cache type 93 func (c *LoadableCache) GetType() string { 94 return LoadableType 95 }