diff --git a/br/pkg/pdutil/pd.go b/br/pkg/pdutil/pd.go index 16b8ce3dbac58..08cfebe1ef7e0 100644 --- a/br/pkg/pdutil/pd.go +++ b/br/pkg/pdutil/pd.go @@ -142,6 +142,7 @@ func pdRequest( return nil, errors.Trace(err) } reqURL := fmt.Sprintf("%s/%s", u, prefix) +<<<<<<< HEAD req, err := http.NewRequestWithContext(ctx, method, reqURL, body) if err != nil { return nil, errors.Trace(err) @@ -152,6 +153,19 @@ func pdRequest( } count := 0 for { +======= + var ( + req *http.Request + resp *http.Response + ) + count := 0 + for { + req, err = http.NewRequestWithContext(ctx, method, reqURL, body) + if err != nil { + return 0, nil, errors.Trace(err) + } + resp, err = cli.Do(req) //nolint:bodyclose +>>>>>>> b9b336843bc (lightning: every HTTP retry should use its own request (#47959)) count++ if count > pdRequestRetryTime || resp.StatusCode < 500 { break diff --git a/br/pkg/pdutil/pd_serial_test.go b/br/pkg/pdutil/pd_serial_test.go index 05f0d34aa2ef2..9d9afc5ec89cd 100644 --- a/br/pkg/pdutil/pd_serial_test.go +++ b/br/pkg/pdutil/pd_serial_test.go @@ -3,6 +3,7 @@ package pdutil import ( + "bytes" "context" "encoding/hex" "encoding/json" @@ -183,8 +184,16 @@ func TestPDRequestRetry(t *testing.T) { w.WriteHeader(http.StatusOK) })) cli := http.DefaultClient + cli.Transport = http.DefaultTransport.(*http.Transport).Clone() + // although the real code doesn't disable keep alive, we need to disable it + // in test to avoid the connection being reused and #47930 can't appear. The + // real code will only meet #47930 when go's internal http client just dropped + // all idle connections. + cli.Transport.(*http.Transport).DisableKeepAlives = true + taddr := ts.URL - _, reqErr := pdRequest(ctx, taddr, "", cli, http.MethodGet, nil) + body := bytes.NewBuffer([]byte("test")) + _, reqErr := pdRequest(ctx, taddr, "", cli, http.MethodPost, body) require.NoError(t, reqErr) ts.Close() count = 0