From 5f423d7ba8d7d02c098f83d846c18bdf2a9dbf34 Mon Sep 17 00:00:00 2001 From: Ondra Kupka Date: Mon, 27 Oct 2025 14:56:40 +0100 Subject: [PATCH] controller/podautoscaler: Improve goroutine mgmt Make sure all threads are terminated when Run returns. --- pkg/controller/podautoscaler/horizontal.go | 14 ++++++++++---- pkg/controller/podautoscaler/horizontal_test.go | 9 +++++++-- 2 files changed, 17 insertions(+), 6 deletions(-) diff --git a/pkg/controller/podautoscaler/horizontal.go b/pkg/controller/podautoscaler/horizontal.go index 75a05e65c9f..def33660183 100644 --- a/pkg/controller/podautoscaler/horizontal.go +++ b/pkg/controller/podautoscaler/horizontal.go @@ -199,20 +199,26 @@ func NewHorizontalController( // Run begins watching and syncing. func (a *HorizontalController) Run(ctx context.Context, workers int) { defer utilruntime.HandleCrash() - defer a.queue.ShutDown() logger := klog.FromContext(ctx) logger.Info("Starting HPA controller") - defer logger.Info("Shutting down HPA controller") + + var wg sync.WaitGroup + defer func() { + logger.Info("Shutting down HPA controller") + a.queue.ShutDown() + wg.Wait() + }() if !cache.WaitForNamedCacheSyncWithContext(ctx, a.hpaListerSynced, a.podListerSynced) { return } for i := 0; i < workers; i++ { - go wait.UntilWithContext(ctx, a.worker, time.Second) + wg.Go(func() { + wait.UntilWithContext(ctx, a.worker, time.Second) + }) } - <-ctx.Done() } diff --git a/pkg/controller/podautoscaler/horizontal_test.go b/pkg/controller/podautoscaler/horizontal_test.go index 58b35b843f5..3395b1e8164 100644 --- a/pkg/controller/podautoscaler/horizontal_test.go +++ b/pkg/controller/podautoscaler/horizontal_test.go @@ -825,9 +825,14 @@ func coolCPUCreationTime() metav1.Time { func (tc *testCase) runTestWithController(t *testing.T, hpaController *HorizontalController, informerFactory informers.SharedInformerFactory) { ctx, cancel := context.WithCancel(context.Background()) - defer cancel() informerFactory.Start(ctx.Done()) - go hpaController.Run(ctx, 5) + + var wg sync.WaitGroup + wg.Go(func() { + hpaController.Run(ctx, 5) + }) + defer wg.Wait() + defer cancel() tc.Lock() shouldWait := tc.verifyEvents