Skip to content

Commit 7fc0512

Browse files
rpc: Avoid unnecessary RST_STREAM and PING frames causing GOAWAYs (#1839)
1 parent 36af339 commit 7fc0512

File tree

2 files changed

+12
-4
lines changed

2 files changed

+12
-4
lines changed

rpc/http.go

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -183,13 +183,21 @@ func newClientTransportHTTP(endpoint string, cfg *clientConfig) reconnectFunc {
183183
}
184184
}
185185

186+
// cleanlyCloseBody avoids sending unnecessary RST_STREAM and PING frames by
187+
// ensuring the whole body is read before being closed.
188+
// See https://blog.cloudflare.com/go-and-enhance-your-calm/#reading-bodies-in-go-can-be-unintuitive
189+
func cleanlyCloseBody(body io.ReadCloser) error {
190+
io.Copy(io.Discard, body)
191+
return body.Close()
192+
}
193+
186194
func (c *Client) sendHTTP(ctx context.Context, op *requestOp, msg interface{}) error {
187195
hc := c.writeConn.(*httpConn)
188196
respBody, err := hc.doRequest(ctx, msg)
189197
if err != nil {
190198
return err
191199
}
192-
defer respBody.Close()
200+
defer cleanlyCloseBody(respBody)
193201

194202
var resp jsonrpcMessage
195203
batch := [1]*jsonrpcMessage{&resp}
@@ -206,7 +214,7 @@ func (c *Client) sendBatchHTTP(ctx context.Context, op *requestOp, msgs []*jsonr
206214
if err != nil {
207215
return err
208216
}
209-
defer respBody.Close()
217+
defer cleanlyCloseBody(respBody)
210218

211219
var respmsgs []*jsonrpcMessage
212220
if err := json.NewDecoder(respBody).Decode(&respmsgs); err != nil {
@@ -251,7 +259,7 @@ func (hc *httpConn) doRequest(ctx context.Context, msg interface{}) (io.ReadClos
251259
if _, err := buf.ReadFrom(resp.Body); err == nil {
252260
body = buf.Bytes()
253261
}
254-
resp.Body.Close()
262+
cleanlyCloseBody(resp.Body)
255263
return nil, HTTPError{
256264
Status: resp.Status,
257265
StatusCode: resp.StatusCode,

rpc/http_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ func confirmHTTPRequestYieldsStatusCode(t *testing.T, method, contentType, body
107107
if err != nil {
108108
t.Fatalf("request failed: %v", err)
109109
}
110-
resp.Body.Close()
110+
cleanlyCloseBody(resp.Body)
111111
confirmStatusCode(t, resp.StatusCode, expectedStatusCode)
112112
}
113113

0 commit comments

Comments
 (0)