From 06f6f7d444a1ea6ed66b350bdad5be20f319462c Mon Sep 17 00:00:00 2001 From: Zbynek Roubalik Date: Thu, 15 Dec 2022 10:38:51 +0100 Subject: [PATCH] fix: properly retrieve and close scalers cache (#4012) Signed-off-by: Zbynek Roubalik Signed-off-by: Zbynek Roubalik --- CHANGELOG.md | 2 +- pkg/scaling/cache/scalers_cache.go | 7 ++++--- pkg/scaling/scale_handler.go | 22 +++++++++++++--------- 3 files changed, 18 insertions(+), 13 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 595b9f6b28a..40a2495a43a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -59,7 +59,7 @@ Here is an overview of all new **experimental** features: ### Fixes -- **General**: TODO ([#TODO](https://github.com/kedacore/keda/issues/TODO)) +- **General**: Properly retrieve and close scalers cache ([#4011](https://github.com/kedacore/keda/issues/4011)) ### Deprecations diff --git a/pkg/scaling/cache/scalers_cache.go b/pkg/scaling/cache/scalers_cache.go index 3059fb7e33d..813ed7b4bfc 100644 --- a/pkg/scaling/cache/scalers_cache.go +++ b/pkg/scaling/cache/scalers_cache.go @@ -36,9 +36,10 @@ import ( var log = logf.Log.WithName("scalers_cache") type ScalersCache struct { - ScaledObject *kedav1alpha1.ScaledObject - Scalers []ScalerBuilder - Recorder record.EventRecorder + ScaledObject *kedav1alpha1.ScaledObject + Scalers []ScalerBuilder + ScalableObjectGeneration int64 + Recorder record.EventRecorder } type ScalerBuilder struct { diff --git a/pkg/scaling/scale_handler.go b/pkg/scaling/scale_handler.go index dc1b919eaf4..39879cf743c 100644 --- a/pkg/scaling/scale_handler.go +++ b/pkg/scaling/scale_handler.go @@ -187,7 +187,7 @@ func (h *scaleHandler) GetScalersCache(ctx context.Context, scalableObject inter key := withTriggers.GenerateIdentifier() generation := withTriggers.Generation - return h.performGetScalersCache(ctx, key, scalableObject, generation, "", "", "") + return h.performGetScalersCache(ctx, key, scalableObject, &generation, "", "", "") } // getScalersCacheForScaledObject returns cache for input ScaledObject, referenced by name and namespace @@ -195,16 +195,16 @@ func (h *scaleHandler) GetScalersCache(ctx context.Context, scalableObject inter func (h *scaleHandler) getScalersCacheForScaledObject(ctx context.Context, scaledObjectName, scaledObjectNamespace string) (*cache.ScalersCache, error) { key := kedav1alpha1.GenerateIdentifier("ScaledObject", scaledObjectNamespace, scaledObjectName) - return h.performGetScalersCache(ctx, key, nil, -1, "ScaledObject", scaledObjectNamespace, scaledObjectName) + return h.performGetScalersCache(ctx, key, nil, nil, "ScaledObject", scaledObjectNamespace, scaledObjectName) } // performGetScalersCache returns cache for input scalableObject, it is common code used by GetScalersCache() and getScalersCacheForScaledObject() methods -func (h *scaleHandler) performGetScalersCache(ctx context.Context, key string, scalableObject interface{}, scalableObjectGeneration int64, scalableObjectKind, scalableObjectNamespace, scalableObjectName string) (*cache.ScalersCache, error) { +func (h *scaleHandler) performGetScalersCache(ctx context.Context, key string, scalableObject interface{}, scalableObjectGeneration *int64, scalableObjectKind, scalableObjectNamespace, scalableObjectName string) (*cache.ScalersCache, error) { h.scalerCachesLock.RLock() if cache, ok := h.scalerCaches[key]; ok { // generation was specified -> let's include it in the check as well - if scalableObjectGeneration != -1 { - if scalableObject != nil && cache.ScaledObject != nil && cache.ScaledObject.Generation == scalableObjectGeneration { + if scalableObjectGeneration != nil { + if cache.ScalableObjectGeneration == *scalableObjectGeneration { h.scalerCachesLock.RUnlock() return cache, nil } @@ -219,10 +219,13 @@ func (h *scaleHandler) performGetScalersCache(ctx context.Context, key string, s defer h.scalerCachesLock.Unlock() if cache, ok := h.scalerCaches[key]; ok { // generation was specified -> let's include it in the check as well - if scalableObjectGeneration != -1 { - if scalableObject != nil && cache.ScaledObject != nil && cache.ScaledObject.Generation == scalableObjectGeneration { + if scalableObjectGeneration != nil { + if cache.ScalableObjectGeneration == *scalableObjectGeneration { return cache, nil } + // object was found in cache, but the generation is not correct, + // let's close scalers in the cache and proceed further to recreate the cache + cache.Close(ctx) } else { return cache, nil } @@ -269,8 +272,9 @@ func (h *scaleHandler) performGetScalersCache(ctx context.Context, key string, s } newCache := &cache.ScalersCache{ - Scalers: scalers, - Recorder: h.recorder, + Scalers: scalers, + ScalableObjectGeneration: withTriggers.Generation, + Recorder: h.recorder, } switch obj := scalableObject.(type) { case *kedav1alpha1.ScaledObject: