Fix leaking goroutines in QuotaEvaluator

This commit is contained in:
Wojciech Tyczyński 2022-05-26 21:10:10 +02:00
parent eb37a5d9c1
commit 9d974e6e89

View File

@ -115,7 +115,7 @@ func NewQuotaEvaluator(quotaAccessor QuotaAccessor, ignoredResources map[schema.
config = &resourcequotaapi.Configuration{} config = &resourcequotaapi.Configuration{}
} }
return &quotaEvaluator{ evaluator := &quotaEvaluator{
quotaAccessor: quotaAccessor, quotaAccessor: quotaAccessor,
lockAcquisitionFunc: lockAcquisitionFunc, lockAcquisitionFunc: lockAcquisitionFunc,
@ -131,15 +131,28 @@ func NewQuotaEvaluator(quotaAccessor QuotaAccessor, ignoredResources map[schema.
stopCh: stopCh, stopCh: stopCh,
config: config, config: config,
} }
// The queue underneath is starting a goroutine for metrics
// exportint that is only stopped on calling ShutDown.
// Given that QuotaEvaluator is created for each layer of apiserver
// and often not started for some of those (e.g. aggregated apiserver)
// we explicitly shut it down on stopCh signal even if it wasn't
// effectively started.
go evaluator.shutdownOnStop()
return evaluator
} }
// Run begins watching and syncing. // start begins watching and syncing.
func (e *quotaEvaluator) run() { func (e *quotaEvaluator) start() {
defer utilruntime.HandleCrash() defer utilruntime.HandleCrash()
for i := 0; i < e.workers; i++ { for i := 0; i < e.workers; i++ {
go wait.Until(e.doWork, time.Second, e.stopCh) go wait.Until(e.doWork, time.Second, e.stopCh)
} }
}
func (e *quotaEvaluator) shutdownOnStop() {
<-e.stopCh <-e.stopCh
klog.Infof("Shutting down quota evaluator") klog.Infof("Shutting down quota evaluator")
e.queue.ShutDown() e.queue.ShutDown()
@ -590,9 +603,7 @@ func getScopeSelectorsFromQuota(quota corev1.ResourceQuota) []corev1.ScopedResou
} }
func (e *quotaEvaluator) Evaluate(a admission.Attributes) error { func (e *quotaEvaluator) Evaluate(a admission.Attributes) error {
e.init.Do(func() { e.init.Do(e.start)
go e.run()
})
// is this resource ignored? // is this resource ignored?
gvr := a.GetResource() gvr := a.GetResource()