Optimize watchcache by not starting a gorotuine for all Get/List requests setting RV=0

This commit is contained in:
wojtekt 2021-09-24 14:14:19 +02:00
parent 6c45f6e32b
commit 37f93fc63d
2 changed files with 23 additions and 13 deletions

View File

@ -210,7 +210,7 @@ TestCase:
break TestCase break TestCase
default: default:
} }
w.Stop() w.stopThreadUnsafe()
} }
} }
@ -551,7 +551,7 @@ func TestCacheWatcherStoppedInAnotherGoroutine(t *testing.T) {
case <-time.After(time.Second): case <-time.After(time.Second):
t.Fatal("expected received a event on ResultChan") t.Fatal("expected received a event on ResultChan")
} }
w.Stop() w.stopThreadUnsafe()
} }
} }

View File

@ -420,6 +420,15 @@ func (w *watchCache) List() []interface{} {
// You HAVE TO explicitly call w.RUnlock() after this function. // You HAVE TO explicitly call w.RUnlock() after this function.
func (w *watchCache) waitUntilFreshAndBlock(resourceVersion uint64, trace *utiltrace.Trace) error { func (w *watchCache) waitUntilFreshAndBlock(resourceVersion uint64, trace *utiltrace.Trace) error {
startTime := w.clock.Now() startTime := w.clock.Now()
// In case resourceVersion is 0, we accept arbitrarily stale result.
// As a result, the condition in the below for loop will never be
// satisfied (w.resourceVersion is never negative), this call will
// never hit the w.cond.Wait().
// As a result - we can optimize the code by not firing the wakeup
// function (and avoid starting a gorotuine), especially given that
// resourceVersion=0 is the most common case.
if resourceVersion > 0 {
go func() { go func() {
// Wake us up when the time limit has expired. The docs // Wake us up when the time limit has expired. The docs
// promise that time.After (well, NewTimer, which it calls) // promise that time.After (well, NewTimer, which it calls)
@ -431,6 +440,7 @@ func (w *watchCache) waitUntilFreshAndBlock(resourceVersion uint64, trace *utilt
<-w.clock.After(blockTimeout) <-w.clock.After(blockTimeout)
w.cond.Broadcast() w.cond.Broadcast()
}() }()
}
w.RLock() w.RLock()
if trace != nil { if trace != nil {