github.com/argoproj/argo-cd/v2@v2.10.5/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([]interface{}{})
    21  }
    22  
    23  // compile-time validation of adherance 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  	i.memCache.Set(item.Key, buf, item.Expiration)
    37  	return nil
    38  }
    39  
    40  // HasSame returns true if key with the same value already present in cache
    41  func (i *InMemoryCache) HasSame(key string, obj interface{}) (bool, error) {
    42  	var buf bytes.Buffer
    43  	err := gob.NewEncoder(&buf).Encode(obj)
    44  	if err != nil {
    45  		return false, err
    46  	}
    47  
    48  	bufIf, found := i.memCache.Get(key)
    49  	if !found {
    50  		return false, nil
    51  	}
    52  	existingBuf, ok := bufIf.(bytes.Buffer)
    53  	if !ok {
    54  		panic(fmt.Errorf("InMemoryCache has unexpected entry: %v", existingBuf))
    55  	}
    56  	return bytes.Equal(buf.Bytes(), existingBuf.Bytes()), nil
    57  }
    58  
    59  func (i *InMemoryCache) Get(key string, obj interface{}) error {
    60  	bufIf, found := i.memCache.Get(key)
    61  	if !found {
    62  		return ErrCacheMiss
    63  	}
    64  	buf := bufIf.(bytes.Buffer)
    65  	return gob.NewDecoder(&buf).Decode(obj)
    66  }
    67  
    68  func (i *InMemoryCache) Delete(key string) error {
    69  	i.memCache.Delete(key)
    70  	return nil
    71  }
    72  
    73  func (i *InMemoryCache) Flush() {
    74  	i.memCache.Flush()
    75  }
    76  
    77  func (i *InMemoryCache) OnUpdated(ctx context.Context, key string, callback func() error) error {
    78  	return nil
    79  }
    80  
    81  func (i *InMemoryCache) NotifyUpdated(key string) error {
    82  	return nil
    83  }
    84  
    85  // Items return a list of items in the cache; requires passing a constructor function
    86  // so that the items can be decoded from gob format.
    87  func (i *InMemoryCache) Items(createNewObject func() interface{}) (map[string]interface{}, error) {
    88  
    89  	result := map[string]interface{}{}
    90  
    91  	for key, value := range i.memCache.Items() {
    92  
    93  		buf := value.Object.(bytes.Buffer)
    94  		obj := createNewObject()
    95  		err := gob.NewDecoder(&buf).Decode(obj)
    96  		if err != nil {
    97  			return nil, err
    98  		}
    99  
   100  		result[key] = obj
   101  
   102  	}
   103  
   104  	return result, nil
   105  }