Skip to content

Commit fc03f3e

Browse files
authored
Merge pull request kubernetes#126125 from mprahl/stop-idempotent
Allow calling Stop multiple times on RetryWatcher
2 parents 1854839 + a54ba91 commit fc03f3e

File tree

2 files changed

+13
-1
lines changed

2 files changed

+13
-1
lines changed

staging/src/k8s.io/client-go/tools/watch/retrywatcher.go

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import (
2222
"fmt"
2323
"io"
2424
"net/http"
25+
"sync"
2526
"time"
2627

2728
apierrors "k8s.io/apimachinery/pkg/api/errors"
@@ -53,6 +54,7 @@ type RetryWatcher struct {
5354
stopChan chan struct{}
5455
doneChan chan struct{}
5556
minRestartDelay time.Duration
57+
stopChanLock sync.Mutex
5658
}
5759

5860
// NewRetryWatcher creates a new RetryWatcher.
@@ -286,7 +288,15 @@ func (rw *RetryWatcher) ResultChan() <-chan watch.Event {
286288

287289
// Stop implements Interface.
288290
func (rw *RetryWatcher) Stop() {
289-
close(rw.stopChan)
291+
rw.stopChanLock.Lock()
292+
defer rw.stopChanLock.Unlock()
293+
294+
// Prevent closing an already closed channel to prevent a panic
295+
select {
296+
case <-rw.stopChan:
297+
default:
298+
close(rw.stopChan)
299+
}
290300
}
291301

292302
// Done allows the caller to be notified when Retry watcher stops.

staging/src/k8s.io/client-go/tools/watch/retrywatcher_test.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -585,6 +585,8 @@ func TestRetryWatcherToFinishWithUnreadEvents(t *testing.T) {
585585
// Give the watcher a chance to get to sending events (blocking)
586586
time.Sleep(10 * time.Millisecond)
587587

588+
watcher.Stop()
589+
// Verify a second stop does not cause a panic
588590
watcher.Stop()
589591

590592
maxTime := time.Second

0 commit comments

Comments
 (0)