From a4782c8c1b832e78ee8aef3758a5ce0d27da899e Mon Sep 17 00:00:00 2001 From: Alejandro Ruiz Date: Thu, 18 Jul 2024 17:46:19 +0200 Subject: [PATCH] perf(schema): replace LRUExpire cache --- pkg/internal/cache/cache.go | 14 +++++++++-- pkg/internal/cache/expiring.go | 46 ++++++++++++++++++++++++++++++++++ 2 files changed, 58 insertions(+), 2 deletions(-) create mode 100644 pkg/internal/cache/expiring.go diff --git a/pkg/internal/cache/cache.go b/pkg/internal/cache/cache.go index bec5109f..aae6c593 100644 --- a/pkg/internal/cache/cache.go +++ b/pkg/internal/cache/cache.go @@ -1,6 +1,11 @@ package cache -import "time" +import ( + "os" + "time" +) + +const cacheBackendEnvVar = "CATTLE_STEVE_CACHE_BACKEND" type Cache[K, V any] interface { Get(K) (V, bool) @@ -11,5 +16,10 @@ type Cache[K, V any] interface { } func NewCache[K, V any](maxSize int, ttl time.Duration) Cache[K, V] { - return newLRUExpire[K, V](maxSize, ttl) + switch os.Getenv(cacheBackendEnvVar) { + case "LRU", "lru": + return newLRUExpire[K, V](maxSize, ttl) + default: + return newExpiring[K, V](maxSize, ttl) + } } diff --git a/pkg/internal/cache/expiring.go b/pkg/internal/cache/expiring.go new file mode 100644 index 00000000..0c4ef0a6 --- /dev/null +++ b/pkg/internal/cache/expiring.go @@ -0,0 +1,46 @@ +package cache + +import ( + "time" + + "github.com/sirupsen/logrus" + "k8s.io/apimachinery/pkg/util/cache" +) + +func newExpiring[K, V any](maxSize int, ttl time.Duration) Cache[K, V] { + return &wrapExpiring[K, V]{maxSize: maxSize, ttl: ttl, cache: cache.NewExpiring()} +} + +// wrapExpiring imposes some static type restrictions around a generic cache.Expiring cache +type wrapExpiring[K, V any] struct { + maxSize int + ttl time.Duration + cache *cache.Expiring +} + +func (w wrapExpiring[K, V]) Get(k K) (V, bool) { + if v, ok := w.cache.Get(k); ok { + return v.(V), true + } + // zero value of V + return *new(V), false +} + +func (w wrapExpiring[K, V]) Set(k K, v V) { + w.cache.Set(k, v, w.ttl) + if current, max := w.cache.Len(), w.maxSize; current >= max { + logrus.WithField("max", max).WithField("current", current).Warnf("cache reached soft limit") + } +} + +func (w wrapExpiring[K, V]) Delete(k K) { + w.cache.Delete(k) +} + +func (w wrapExpiring[K, V]) Len() int { + return w.cache.Len() +} + +func (w wrapExpiring[K, V]) Reset() { + w.cache = cache.NewExpiring() +}