Merge pull request #83373 from liggitt/automated-cherry-pick-of-#83333-upstream-release-1.14
Automated cherry pick of #83333: Don't leak a go routine on timeout Kubernetes-commit: b1d90868ad049c8db13d4240f21e13ce3ec550a3
This commit is contained in:
commit
d62eae5221
|
@ -28,6 +28,7 @@ import (
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
apierrors "k8s.io/apimachinery/pkg/api/errors"
|
apierrors "k8s.io/apimachinery/pkg/api/errors"
|
||||||
|
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
|
||||||
"k8s.io/apiserver/pkg/endpoints/metrics"
|
"k8s.io/apiserver/pkg/endpoints/metrics"
|
||||||
apirequest "k8s.io/apiserver/pkg/endpoints/request"
|
apirequest "k8s.io/apiserver/pkg/endpoints/request"
|
||||||
)
|
)
|
||||||
|
@ -92,7 +93,8 @@ func (t *timeoutHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
errCh := make(chan interface{})
|
// resultCh is used as both errCh and stopCh
|
||||||
|
resultCh := make(chan interface{})
|
||||||
tw := newTimeoutWriter(w)
|
tw := newTimeoutWriter(w)
|
||||||
go func() {
|
go func() {
|
||||||
defer func() {
|
defer func() {
|
||||||
|
@ -103,17 +105,34 @@ func (t *timeoutHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||||
buf = buf[:runtime.Stack(buf, false)]
|
buf = buf[:runtime.Stack(buf, false)]
|
||||||
err = fmt.Sprintf("%v\n%s", err, buf)
|
err = fmt.Sprintf("%v\n%s", err, buf)
|
||||||
}
|
}
|
||||||
errCh <- err
|
resultCh <- err
|
||||||
}()
|
}()
|
||||||
t.handler.ServeHTTP(tw, r)
|
t.handler.ServeHTTP(tw, r)
|
||||||
}()
|
}()
|
||||||
select {
|
select {
|
||||||
case err := <-errCh:
|
case err := <-resultCh:
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
case <-after:
|
case <-after:
|
||||||
|
defer func() {
|
||||||
|
// resultCh needs to have a reader, since the function doing
|
||||||
|
// the work needs to send to it. This is defer'd to ensure it runs
|
||||||
|
// ever if the post timeout work itself panics.
|
||||||
|
go func() {
|
||||||
|
res := <-resultCh
|
||||||
|
if res != nil {
|
||||||
|
switch t := res.(type) {
|
||||||
|
case error:
|
||||||
|
utilruntime.HandleError(t)
|
||||||
|
default:
|
||||||
|
utilruntime.HandleError(fmt.Errorf("%v", res))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
}()
|
||||||
|
|
||||||
postTimeoutFn()
|
postTimeoutFn()
|
||||||
tw.timeout(err)
|
tw.timeout(err)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue