Skip to content

Commit 874b022

Browse files
committed
Wait for NonLeaderElectionRunnables to terminate
This commit ensures the main Start does not return prior to NonLeaderElectionRunnables finishing.
1 parent c4893e0 commit 874b022

File tree

1 file changed

+25
-4
lines changed

1 file changed

+25
-4
lines changed

pkg/manager/internal.go

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -436,8 +436,14 @@ func (cm *controllerManager) serveHealthProbes(stop <-chan struct{}) {
436436
}
437437

438438
func (cm *controllerManager) Start(stop <-chan struct{}) error {
439-
// join the passed-in stop channel as an upstream feeding into cm.internalStopper
440-
defer close(cm.internalStopper)
439+
// This will block until all runnables started via
440+
// startNonLeaderElectionRunnables finish.
441+
doneCh := make(chan struct{})
442+
defer func() {
443+
// join the passed-in stop channel as an upstream feeding into cm.internalStopper
444+
close(cm.internalStopper)
445+
<-doneCh
446+
}()
441447

442448
// initialize this here so that we reset the signal channel state on every start
443449
cm.errSignal = &errSignaler{errSignal: make(chan struct{})}
@@ -454,7 +460,7 @@ func (cm *controllerManager) Start(stop <-chan struct{}) error {
454460
go cm.serveHealthProbes(cm.internalStop)
455461
}
456462

457-
go cm.startNonLeaderElectionRunnables()
463+
go cm.startNonLeaderElectionRunnables(doneCh)
458464

459465
if cm.resourceLock != nil {
460466
err := cm.startLeaderElection()
@@ -477,12 +483,13 @@ func (cm *controllerManager) Start(stop <-chan struct{}) error {
477483
}
478484
}
479485

480-
func (cm *controllerManager) startNonLeaderElectionRunnables() {
486+
func (cm *controllerManager) startNonLeaderElectionRunnables(doneCh chan<- struct{}) {
481487
cm.mu.Lock()
482488
defer cm.mu.Unlock()
483489

484490
cm.waitForCache()
485491

492+
returnCh := make(chan struct{})
486493
// Start the non-leaderelection Runnables after the cache has synced
487494
for _, c := range cm.nonLeaderElectionRunnables {
488495
// Controllers block, but we want to return an error if any have an error starting.
@@ -495,8 +502,22 @@ func (cm *controllerManager) startNonLeaderElectionRunnables() {
495502
// we use %T here because we don't have a good stand-in for "name",
496503
// and the full runnable might not serialize (mutexes, etc)
497504
log.V(1).Info("non-leader-election runnable finished", "runnable type", fmt.Sprintf("%T", ctrl))
505+
returnCh <- struct{}{}
498506
}()
499507
}
508+
509+
doneCount := 0
510+
511+
numRunners := len(cm.nonLeaderElectionRunnables)
512+
for doneCount < numRunners {
513+
select {
514+
case <-returnCh:
515+
doneCount++
516+
default:
517+
}
518+
}
519+
close(returnCh)
520+
close(doneCh)
500521
}
501522

502523
func (cm *controllerManager) startLeaderElectionRunnables() {

0 commit comments

Comments
 (0)