try to fix data race with http lib

WARNING: DATA RACE
Write at 0x00c008121e80 by goroutine 235:
  bytes.(*Reader).WriteTo()
      /usr/local/go/src/bytes/reader.go:139 +0x45
  github.com/molecula/featurebase/v2/http.nopCloser.WriteTo()
      <autogenerated>:1 +0x5d
  io.copyBuffer()
      /usr/local/go/src/io/io.go:391 +0x482
  io.Copy()
      /usr/local/go/src/io/io.go:368 +0x78
  net/http.(*transferWriter).doBodyCopy()
      /usr/local/go/src/net/http/transfer.go:400 +0x2f
  net/http.(*transferWriter).writeBody()
      /usr/local/go/src/net/http/transfer.go:364 +0xc9a
  net/http.(*Request).write()
      /usr/local/go/src/net/http/request.go:682 +0x887
  net/http.(*persistConn).writeLoop()
      /usr/local/go/src/net/http/transport.go:2343 +0x349

Previous write at 0x00c008121e80 by goroutine 192:
  bytes.(*Reader).Seek()
      /usr/local/go/src/bytes/reader.go:118 +0x824
  github.com/molecula/featurebase/v2/http.(*InternalClient).doWithRetry()
      /go/src/github.com/molecula/featurebase/http/client.go:1773 +0x86d
  github.com/molecula/featurebase/v2/http.(*InternalClient).executeRequest()
      /go/src/github.com/molecula/featurebase/http/client.go:1806 +0x15b
  github.com/molecula/featurebase/v2/http.(*InternalClient).CreateIndex()
      /go/src/github.com/molecula/featurebase/http/client.go:433 +0xbf8
  github.com/molecula/featurebase/v2/server_test.TestMain_Set_Quick.func1()
      /go/src/github.com/molecula/featurebase/server/server_test.go:64 +0x624
  testing.tRunner()
      /usr/local/go/src/testing/testing.go:1123 +0x202

Goroutine 235 (running) created at:
  net/http.(*Transport).dialConn()
      /usr/local/go/src/net/http/transport.go:1709 +0xc30
  net/http.(*Transport).dialConnFor()
      /usr/local/go/src/net/http/transport.go:1421 +0x151

Goroutine 192 (running) created at:
  testing.(*T).Run()
      /usr/local/go/src/testing/testing.go:1168 +0x5bb
  github.com/molecula/featurebase/v2/server_test.TestMain_Set_Quick()
      /go/src/github.com/molecula/featurebase/server/server_test.go:45 +0x116
  testing.tRunner()
      /usr/local/go/src/testing/testing.go:1123 +0x202
This commit is contained in:
Matthew Jaffee 2021-12-20 21:48:45 -06:00
parent f676fbfc51
commit d3b9193c8d

View file

@ -1755,22 +1755,22 @@ func (n nopCloser) Close() error {
func (c *InternalClient) doWithRetry(req *http.Request) (*http.Response, error) {
sleepDuration := time.Second
newBody := nopCloser{}
var bod []byte
var err error
if req.Body != nil {
bod, err := ioutil.ReadAll(req.Body)
bod, err = ioutil.ReadAll(req.Body)
if err != nil {
return nil, errors.Wrap(err, "reading body")
}
newBody.Reader = bytes.NewReader(bod)
req.Body = newBody
req.Body = nopCloser{bytes.NewReader(bod)}
}
resp, err := c.httpClient.Do(req)
// start timer after first request, so if retryPeriod > 0 we
// pretty much always do at least one retry
start := time.Now()
for ; err != nil || resp.StatusCode < 200 || resp.StatusCode >= 300; resp, err = c.httpClient.Do(req) {
if newBody.Reader != nil {
newBody.Seek(0, io.SeekStart)
if req.Body != nil {
req.Body = nopCloser{bytes.NewReader(bod)} // can't seek due to races with http lib internals
}
if time.Since(start) > c.retryPeriod {
break