github.com/argoproj/argo-cd@v1.8.7/util/cache/twolevelclient.go (about) 1 package cache 2 3 import ( 4 "context" 5 "time" 6 7 log "github.com/sirupsen/logrus" 8 ) 9 10 // NewTwoLevelClient creates cache client that proxies requests to given external cache and tries to minimize 11 // number of requests to external client by storing cache entries in local in-memory cache. 12 func NewTwoLevelClient(client CacheClient, inMemoryExpiration time.Duration) *twoLevelClient { 13 return &twoLevelClient{inMemoryCache: NewInMemoryCache(inMemoryExpiration), externalCache: client} 14 } 15 16 type twoLevelClient struct { 17 inMemoryCache *InMemoryCache 18 externalCache CacheClient 19 } 20 21 // Set stores the given value in both in-memory and external cache. 22 // Skip storing the value in external cache if the same value already exists in memory to avoid requesting external cache. 23 func (c *twoLevelClient) Set(item *Item) error { 24 has, err := c.inMemoryCache.HasSame(item.Key, item.Object) 25 if has { 26 return nil 27 } 28 if err != nil { 29 log.Warnf("Failed to check key '%s' in in-memory cache: %v", item.Key, err) 30 } 31 err = c.inMemoryCache.Set(item) 32 if err != nil { 33 log.Warnf("Failed to save key '%s' in in-memory cache: %v", item.Key, err) 34 } 35 return c.externalCache.Set(item) 36 } 37 38 // Get returns cache value from in-memory cache if it present. Otherwise loads it from external cache and persists 39 // in memory to avoid future requests to external cache. 40 func (c *twoLevelClient) Get(key string, obj interface{}) error { 41 err := c.inMemoryCache.Get(key, obj) 42 if err == nil { 43 return nil 44 } 45 46 err = c.externalCache.Get(key, obj) 47 if err == nil { 48 _ = c.inMemoryCache.Set(&Item{Key: key, Object: obj}) 49 } 50 return err 51 } 52 53 // Delete deletes cache for given key in both in-memory and external cache. 54 func (c *twoLevelClient) Delete(key string) error { 55 err := c.inMemoryCache.Delete(key) 56 if err != nil { 57 return err 58 } 59 return c.externalCache.Delete(key) 60 } 61 62 func (c *twoLevelClient) OnUpdated(ctx context.Context, key string, callback func() error) error { 63 return c.externalCache.OnUpdated(ctx, key, callback) 64 } 65 66 func (c *twoLevelClient) NotifyUpdated(key string) error { 67 return c.externalCache.NotifyUpdated(key) 68 }