Closed mzimmerman closed 3 years ago
Good find @mzimmerman . Am I correct in guessing you are using a single instance of a client concurrently from multiple goroutines?
A recent pull request introduced random 'jitter' into our backoff retry strategy via the math/rand
package. I have just confirmed that the random Source
currently being used is actually not safe for concurrent use. See the godoc:
https://golang.org/pkg/math/rand/#NewSource
NewSource
returns a new pseudo-randomSource
seeded with the given value. Unlike the defaultSource
used by top-level functions, this source is not safe for concurrent use by multiple goroutines.
A work-around for now would be to provide each goroutine with its own exclusive instance of a Client.
Correct. Single instance over multiple goroutines. Is this correct usage or not? Seems like it would be easy enough to put a mutex around the random-jitter-source if there's no conflict otherwise. I've been using the library like this for at least a year and I'd rather not change.
@mzimmerman - We've never sought to limit the usage of a client to a single goroutine. This issue was unintentionally introduced by the pull request I mentioned earlier:
https://github.com/smartystreets/smartystreets-go-sdk/pull/18
================== WARNING: DATA RACE Read at 0x00c005bf9500 by goroutine 2551: math/rand.(rngSource).Uint64() /usr/local/go/src/math/rand/rng.go:239 +0x3e math/rand.(rngSource).Int63() /usr/local/go/src/math/rand/rng.go:234 +0x1d9 math/rand.(Rand).Int63() /usr/local/go/src/math/rand/rand.go:85 +0x125 math/rand.(Rand).Int31() /usr/local/go/src/math/rand/rand.go:99 +0x135 math/rand.(Rand).Int31n() /usr/local/go/src/math/rand/rand.go:131 +0x130 math/rand.(Rand).Intn() /usr/local/go/src/math/rand/rand.go:172 +0x59 github.com/smartystreets/smartystreets-go-sdk/internal/sdk.(RetryClient).backOff() /go/pkg/mod/github.com/smartystreets/smartystreets-go-sdk@v1.8.1/internal/sdk/retry_client.go:71 +0xc7 github.com/smartystreets/smartystreets-go-sdk/internal/sdk.(RetryClient).doBufferedPost() /go/pkg/mod/github.com/smartystreets/smartystreets-go-sdk@v1.8.1/internal/sdk/retry_client.go:54 +0x129 github.com/smartystreets/smartystreets-go-sdk/internal/sdk.(RetryClient).Do() /go/pkg/mod/github.com/smartystreets/smartystreets-go-sdk@v1.8.1/internal/sdk/retry_client.go:34 +0x185 github.com/smartystreets/smartystreets-go-sdk/internal/sdk.(SigningClient).Do() /go/pkg/mod/github.com/smartystreets/smartystreets-go-sdk@v1.8.1/internal/sdk/signing_client.go:28 +0xdc github.com/smartystreets/smartystreets-go-sdk/internal/sdk.(BaseURLClient).Do() /go/pkg/mod/github.com/smartystreets/smartystreets-go-sdk@v1.8.1/internal/sdk/base_url_client.go:27 +0x2ee github.com/smartystreets/smartystreets-go-sdk/internal/sdk.(CustomHeadersClient).Do() /go/pkg/mod/github.com/smartystreets/smartystreets-go-sdk@v1.8.1/internal/sdk/custom_header_client.go:19 +0x94 github.com/smartystreets/smartystreets-go-sdk/internal/sdk.(LicenseClient).Do() /go/pkg/mod/github.com/smartystreets/smartystreets-go-sdk@v1.8.1/internal/sdk/license_client.go:25 +0xaa github.com/smartystreets/smartystreets-go-sdk/internal/sdk.(HTTPSender).Send() /go/pkg/mod/github.com/smartystreets/smartystreets-go-sdk@v1.8.1/internal/sdk/http_sender.go:28 +0x7d github.com/smartystreets/smartystreets-go-sdk/us-extract-api.(Client).SendLookupWithContext() /go/pkg/mod/github.com/smartystreets/smartystreets-go-sdk@v1.8.1/us-extract-api/client.go:33 +0x20a github.com/smartystreets/smartystreets-go-sdk/us-extract-api.(Client).SendLookup() /go/pkg/mod/github.com/smartystreets/smartystreets-go-sdk@v1.8.1/us-extract-api/client.go:23 +0x1be
Previous write at 0x00c005bf9500 by goroutine 1650: math/rand.(rngSource).Uint64() /usr/local/go/src/math/rand/rng.go:239 +0x54 math/rand.(rngSource).Int63() /usr/local/go/src/math/rand/rng.go:234 +0x1d9 math/rand.(Rand).Int63() /usr/local/go/src/math/rand/rand.go:85 +0x125 math/rand.(Rand).Int31() /usr/local/go/src/math/rand/rand.go:99 +0x135 math/rand.(Rand).Int31n() /usr/local/go/src/math/rand/rand.go:131 +0x130 math/rand.(Rand).Intn() /usr/local/go/src/math/rand/rand.go:172 +0x59 github.com/smartystreets/smartystreets-go-sdk/internal/sdk.(RetryClient).backOff() /go/pkg/mod/github.com/smartystreets/smartystreets-go-sdk@v1.8.1/internal/sdk/retry_client.go:71 +0xc7 github.com/smartystreets/smartystreets-go-sdk/internal/sdk.(RetryClient).doBufferedPost() /go/pkg/mod/github.com/smartystreets/smartystreets-go-sdk@v1.8.1/internal/sdk/retry_client.go:54 +0x129 github.com/smartystreets/smartystreets-go-sdk/internal/sdk.(RetryClient).Do() /go/pkg/mod/github.com/smartystreets/smartystreets-go-sdk@v1.8.1/internal/sdk/retry_client.go:34 +0x185 github.com/smartystreets/smartystreets-go-sdk/internal/sdk.(SigningClient).Do() /go/pkg/mod/github.com/smartystreets/smartystreets-go-sdk@v1.8.1/internal/sdk/signing_client.go:28 +0xdc github.com/smartystreets/smartystreets-go-sdk/internal/sdk.(BaseURLClient).Do() /go/pkg/mod/github.com/smartystreets/smartystreets-go-sdk@v1.8.1/internal/sdk/base_url_client.go:27 +0x2ee github.com/smartystreets/smartystreets-go-sdk/internal/sdk.(CustomHeadersClient).Do() /go/pkg/mod/github.com/smartystreets/smartystreets-go-sdk@v1.8.1/internal/sdk/custom_header_client.go:19 +0x94 github.com/smartystreets/smartystreets-go-sdk/internal/sdk.(LicenseClient).Do() /go/pkg/mod/github.com/smartystreets/smartystreets-go-sdk@v1.8.1/internal/sdk/license_client.go:25 +0xaa github.com/smartystreets/smartystreets-go-sdk/internal/sdk.(HTTPSender).Send() /go/pkg/mod/github.com/smartystreets/smartystreets-go-sdk@v1.8.1/internal/sdk/http_sender.go:28 +0x7d github.com/smartystreets/smartystreets-go-sdk/us-extract-api.(Client).SendLookupWithContext() /go/pkg/mod/github.com/smartystreets/smartystreets-go-sdk@v1.8.1/us-extract-api/client.go:33 +0x20a github.com/smartystreets/smartystreets-go-sdk/us-extract-api.(Client).SendLookup() /go/pkg/mod/github.com/smartystreets/smartystreets-go-sdk@v1.8.1/us-extract-api/client.go:23 +0x1be