From 202b4ffdf0cff90b5954d3442a1cdf7f2517cb2d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wojciech=20Tyczy=C5=84ski?= Date: Tue, 21 May 2024 13:58:35 +0200 Subject: [PATCH] Reduce critical section for watchcache.lock --- .../pkg/storage/cacher/watch_cache.go | 31 ++++++++++--------- 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/staging/src/k8s.io/apiserver/pkg/storage/cacher/watch_cache.go b/staging/src/k8s.io/apiserver/pkg/storage/cacher/watch_cache.go index ea2b095d634..1f65be9705e 100644 --- a/staging/src/k8s.io/apiserver/pkg/storage/cacher/watch_cache.go +++ b/staging/src/k8s.io/apiserver/pkg/storage/cacher/watch_cache.go @@ -312,25 +312,26 @@ func (w *watchCache) processEvent(event watch.Event, resourceVersion uint64, upd RecordTime: w.clock.Now(), } + // We can call w.store.Get() outside of a critical section, + // because the w.store itself is thread-safe and the only + // place where w.store is modified is below (via updateFunc) + // and these calls are serialized because reflector is processing + // events one-by-one. + previous, exists, err := w.store.Get(elem) + if err != nil { + return err + } + if exists { + previousElem := previous.(*storeElement) + wcEvent.PrevObject = previousElem.Object + wcEvent.PrevObjLabels = previousElem.Labels + wcEvent.PrevObjFields = previousElem.Fields + } + if err := func() error { - // TODO: We should consider moving this lock below after the watchCacheEvent - // is created. In such situation, the only problematic scenario is Replace() - // happening after getting object from store and before acquiring a lock. - // Maybe introduce another lock for this purpose. w.Lock() defer w.Unlock() - previous, exists, err := w.store.Get(elem) - if err != nil { - return err - } - if exists { - previousElem := previous.(*storeElement) - wcEvent.PrevObject = previousElem.Object - wcEvent.PrevObjLabels = previousElem.Labels - wcEvent.PrevObjFields = previousElem.Fields - } - w.updateCache(wcEvent) w.resourceVersion = resourceVersion defer w.cond.Broadcast()