Skip to content

Commit 98ece15

Browse files
authored
Fix gocoroutine leak (erigontech#16782)
Change the channel to a buffered channel with capacity 1. This ensures that the goroutine can always complete the send, even if the caller has already returned due to context cancellation. The response will simply sit in the channel until it is garbage collected, avoiding the leak.
1 parent bb1ca1b commit 98ece15

File tree

1 file changed

+6
-6
lines changed

1 file changed

+6
-6
lines changed

cl/sentinel/httpreqresp/server.go

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -45,21 +45,21 @@ the following headers have meaning when passed in to the request:
4545
REQRESP-TOPIC - the topic to request with
4646
REQRESP-EXPECTED-CHUNKS - this is an integer, which will be multiplied by 10 to calculate the amount of seconds the peer has to respond with all the data
4747
*/
48-
func Do(handler http.Handler, r *http.Request) (*http.Response, error) {
48+
func Do(handler http.Handler, r *http.Request) (resp *http.Response, err error) {
4949
// TODO: there potentially extra alloc here (responses are bufferd)
5050
// is that a big deal? not sure. maybe can reuse these buffers since they are read once (and known when close) if so
51-
ans := make(chan *http.Response)
51+
ok := make(chan struct{})
5252
go func() {
5353
res := httptest.NewRecorder()
5454
handler.ServeHTTP(res, r)
5555
// linter does not know we are passing the resposne through channel.
5656
// nolint: bodyclose
57-
resp := res.Result()
58-
ans <- resp
57+
resp = res.Result()
58+
close(ok)
5959
}()
6060
select {
61-
case res := <-ans:
62-
return res, nil
61+
case <-ok:
62+
return resp, nil
6363
case <-r.Context().Done():
6464
return nil, r.Context().Err()
6565
}

0 commit comments

Comments
 (0)