github.com/argoproj/argo-cd/v3@v3.2.1/util/cache/inmemory.go (about) 1 package cache 2 3 import ( 4 "bytes" 5 "context" 6 "encoding/gob" 7 "fmt" 8 "time" 9 10 gocache "github.com/patrickmn/go-cache" 11 ) 12 13 func NewInMemoryCache(expiration time.Duration) *InMemoryCache { 14 return &InMemoryCache{ 15 memCache: gocache.New(expiration, 1*time.Minute), 16 } 17 } 18 19 func init() { 20 gob.Register([]any{}) 21 } 22 23 // compile-time validation of adherence of the CacheClient contract 24 var _ CacheClient = &InMemoryCache{} 25 26 type InMemoryCache struct { 27 memCache *gocache.Cache 28 } 29 30 func (i *InMemoryCache) Set(item *Item) error { 31 var buf bytes.Buffer 32 err := gob.NewEncoder(&buf).Encode(item.Object) 33 if err != nil { 34 return err 35 } 36 if item.CacheActionOpts.DisableOverwrite { 37 // go-redis doesn't throw an error on Set with NX, so absorbing here to keep the interface consistent 38 _ = i.memCache.Add(item.Key, buf, item.CacheActionOpts.Expiration) 39 } else { 40 i.memCache.Set(item.Key, buf, item.CacheActionOpts.Expiration) 41 } 42 return nil 43 } 44 45 func (i *InMemoryCache) Rename(oldKey string, newKey string, expiration time.Duration) error { 46 bufIf, found := i.memCache.Get(oldKey) 47 if !found { 48 return ErrCacheMiss 49 } 50 i.memCache.Set(newKey, bufIf, expiration) 51 i.memCache.Delete(oldKey) 52 return nil 53 } 54 55 // HasSame returns true if key with the same value already present in cache 56 func (i *InMemoryCache) HasSame(key string, obj any) (bool, error) { 57 var buf bytes.Buffer 58 err := gob.NewEncoder(&buf).Encode(obj) 59 if err != nil { 60 return false, err 61 } 62 63 bufIf, found := i.memCache.Get(key) 64 if !found { 65 return false, nil 66 } 67 existingBuf, ok := bufIf.(bytes.Buffer) 68 if !ok { 69 panic(fmt.Errorf("InMemoryCache has unexpected entry: %v", existingBuf)) 70 } 71 return bytes.Equal(buf.Bytes(), existingBuf.Bytes()), nil 72 } 73 74 func (i *InMemoryCache) Get(key string, obj any) error { 75 bufIf, found := i.memCache.Get(key) 76 if !found { 77 return ErrCacheMiss 78 } 79 buf := bufIf.(bytes.Buffer) 80 return gob.NewDecoder(&buf).Decode(obj) 81 } 82 83 func (i *InMemoryCache) Delete(key string) error { 84 i.memCache.Delete(key) 85 return nil 86 } 87 88 func (i *InMemoryCache) Flush() { 89 i.memCache.Flush() 90 } 91 92 func (i *InMemoryCache) OnUpdated(_ context.Context, _ string, _ func() error) error { 93 return nil 94 } 95 96 func (i *InMemoryCache) NotifyUpdated(_ string) error { 97 return nil 98 } 99 100 // Items return a list of items in the cache; requires passing a constructor function 101 // so that the items can be decoded from gob format. 102 func (i *InMemoryCache) Items(createNewObject func() any) (map[string]any, error) { 103 result := map[string]any{} 104 105 for key, value := range i.memCache.Items() { 106 buf := value.Object.(bytes.Buffer) 107 obj := createNewObject() 108 err := gob.NewDecoder(&buf).Decode(obj) 109 if err != nil { 110 return nil, err 111 } 112 113 result[key] = obj 114 } 115 116 return result, nil 117 }