fix double close of channel (#2574)

This commit is contained in:
Dave Protasowski 2022-08-17 19:38:48 -04:00 committed by GitHub
parent f78a006943
commit 766f70d9cb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 25 additions and 25 deletions

View File

@ -73,8 +73,11 @@ type Drainer struct {
// timer is used to orchestrate the drain. // timer is used to orchestrate the drain.
timer timer timer timer
// used to synchronize callers of Drain and Reset // used to synchronize callers of Drain
ch chan struct{} drainCh chan struct{}
// used to synchronize Drain and Reset
resetCh chan struct{}
// HealthCheckUAPrefixes are the additional user agent prefixes that trigger the // HealthCheckUAPrefixes are the additional user agent prefixes that trigger the
// drainer's health check // drainer's health check
@ -118,8 +121,8 @@ func (d *Drainer) Drain() {
ch := func() chan struct{} { ch := func() chan struct{} {
d.Lock() d.Lock()
defer d.Unlock() defer d.Unlock()
if d.ch != nil { if d.drainCh != nil {
return d.ch return d.drainCh
} }
if d.QuietPeriod <= 0 { if d.QuietPeriod <= 0 {
@ -127,32 +130,26 @@ func (d *Drainer) Drain() {
} }
timer := newTimer(d.QuietPeriod) timer := newTimer(d.QuietPeriod)
ch := make(chan struct{}) drainCh := make(chan struct{})
resetCh := make(chan struct{})
go func() { go func() {
select { select {
case <-ch: case <-resetCh:
// closed by reset
case <-timer.tickChan(): case <-timer.tickChan():
close(ch)
} }
close(drainCh)
}() }()
d.ch = ch d.drainCh = drainCh
d.resetCh = resetCh
d.timer = timer d.timer = timer
return ch return drainCh
}() }()
<-ch <-ch
} }
func drainTimer(tc <-chan time.Time) {
select {
case <-tc:
default:
}
}
// isHealthcheckRequest validates if the request has a user agent that is for healthcheck // isHealthcheckRequest validates if the request has a user agent that is for healthcheck
func (d *Drainer) isHealthCheckRequest(r *http.Request) bool { func (d *Drainer) isHealthCheckRequest(r *http.Request) bool {
if network.IsKubeletProbe(r) { if network.IsKubeletProbe(r) {
@ -175,16 +172,16 @@ func (d *Drainer) Reset() {
defer d.Unlock() defer d.Unlock()
if d.timer != nil { if d.timer != nil {
if d.timer.Stop() { d.timer.Stop()
d.timer = nil d.timer = nil
} else {
drainTimer(d.timer.tickChan())
}
} }
if d.ch != nil { if d.resetCh != nil {
close(d.ch) close(d.resetCh)
d.ch = nil d.resetCh = nil
}
if d.drainCh != nil {
d.drainCh = nil
} }
} }

View File

@ -542,4 +542,7 @@ func TestReset(t *testing.T) {
if diff > 50*time.Millisecond { if diff > 50*time.Millisecond {
t.Error("expected to drain to wait QuietPeriod time after reset") t.Error("expected to drain to wait QuietPeriod time after reset")
} }
// Calling reset after a drain should succeed
d.Reset()
} }