[release-1.7] Fix nil pointer deref in drain when it's reset (#2652)

* fix nil pointer in the drainer when it's reset

* fix linter

Co-authored-by: Dave Protasowski <dprotaso@gmail.com>
This commit is contained in:
Knative Prow Robot 2022-11-23 01:19:41 +00:00 committed by GitHub
parent 5f920311c9
commit 9d7bd235ce
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 41 additions and 1 deletions

View File

@ -196,7 +196,7 @@ func (d *Drainer) resetTimer() {
d.Lock()
defer d.Unlock()
if d.timer.Stop() {
if d.timer != nil && d.timer.Stop() {
d.timer.Reset(d.QuietPeriod)
}
}

View File

@ -546,3 +546,43 @@ func TestReset(t *testing.T) {
// Calling reset after a drain should succeed
d.Reset()
}
// https://github.com/knative/pkg/issues/2642
func TestResetWithActiveRequests(t *testing.T) {
d := Drainer{
QuietPeriod: 5 * time.Second,
Inner: http.HandlerFunc(func(http.ResponseWriter, *http.Request) {}),
}
trafficStopped := make(chan struct{})
trafficStarted := make(chan struct{})
drainStarted := make(chan struct{})
defer close(trafficStopped)
go func() {
req, _ := http.NewRequest("GET", "knative.dev", nil)
rec := httptest.NewRecorder()
close(trafficStarted)
for {
select {
case <-trafficStopped:
return
default:
d.ServeHTTP(rec, req)
}
}
}()
go func() {
<-trafficStarted
close(drainStarted)
d.Drain()
}()
<-drainStarted
d.Reset()
// We need requests to be active for a bit
time.Sleep(time.Second)
}