diff --git a/pkg/util/wait/wait.go b/pkg/util/wait/wait.go index f31349248d1..853c288dfd6 100644 --- a/pkg/util/wait/wait.go +++ b/pkg/util/wait/wait.go @@ -132,7 +132,12 @@ func poller(interval, timeout time.Duration) WaitFunc { for { select { case <-tick.C: - ch <- struct{}{} + // If the consumer isn't ready for this signal drop it and + // check the other channels. + select { + case ch <- struct{}{}: + default: + } case <-after: return case <-done: diff --git a/pkg/util/wait/wait_test.go b/pkg/util/wait/wait_test.go index 315b9b4ca3a..e130cfcc14f 100644 --- a/pkg/util/wait/wait_test.go +++ b/pkg/util/wait/wait_test.go @@ -257,3 +257,18 @@ func TestWaitFor(t *testing.T) { } } } + +func TestWaitForWithDelay(t *testing.T) { + done := make(chan struct{}) + defer close(done) + WaitFor(poller(time.Millisecond, util.ForeverTestTimeout), func() (bool, error) { + time.Sleep(10 * time.Millisecond) + return true, nil + }, done) + // If polling goroutine doesn't see the done signal it will leak timers. + select { + case done <- struct{}{}: + case <-time.After(util.ForeverTestTimeout): + t.Errorf("expected an ack of the done signal.") + } +}