-
Notifications
You must be signed in to change notification settings - Fork 865
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[keyvault/azsecrets] make azsecrets.Client thread-safe #24032
base: main
Are you sure you want to change the base?
Conversation
Thank you for your contribution @strager! We will review the pull request and get back to you soon. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I left a few comments for maintainers.
serverAuthenticateRequests := atomic.Int32{} | ||
serverAuthenticatedRequests := atomic.Int32{} | ||
var srv *httptest.Server | ||
srv = httptest.NewUnstartedServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Other tests use mock.Server
, but here I used httptest.Server
for two reasons:
mock.Server
is documented to not be safe when used from multiple goroutines.- Even if
mock.Server
was safe at a surface level (e.g. by adding locks), its interface doesn't allow me to handle out-of-order requests.
httptest.Server
has its own issues, but it seemed like the least amount of code to get the test working.
require.GreaterOrEqual(t, int(serverAuthenticateRequests.Load()), 1, "client should have sent at least one preflight request") | ||
require.LessOrEqual(t, int(serverAuthenticateRequests.Load()), concurrentRequestCount, "client should have sent no more preflight requests than client requests") | ||
require.EqualValues(t, concurrentRequestCount, serverAuthenticatedRequests.Load(), "client preflight request count should equal server preflight request count") | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The real assertion is the -race
flag of go test
. The three assertions in the test just make sure the test issued the requests, so they're not doing too much. Should I make the assertions more sophisticated? Is there a way to document that this test is designed to work with -race
?
@@ -7,6 +7,7 @@ | |||
### Breaking Changes | |||
|
|||
### Bugs Fixed | |||
* Fixed data race when using Client from multiple goroutines concurrently. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we reference issue numbers here?
azsecrets.Client uses NewKeyVaultChallengePolicy. This policy is not goroutine-safe, violating the documented requirement that policies are goroutine-safe [1]. This leads to data races which are reported by Go's race detector. Fix NewKeyVaultChallengePolicy to be goroutine-safe using a mutex. This can lead to redundant preflight requests, but at least Go's race detector no longer complains. Test plan: $ cd sdk/security/keyvault/internal/ $ go test -race [1] https://learn.microsoft.com/en-us/azure/developer/go/azure-sdk-core-concepts
3d3cf5c
to
7adba6e
Compare
azsecrets.Client uses NewKeyVaultChallengePolicy. This policy is not goroutine-safe, violating the documented requirement that policies are goroutine-safe [1]. This leads to data races which are reported by Go's race detector.
Fix NewKeyVaultChallengePolicy to be goroutine-safe using a mutex. This can lead to redundant preflight requests, but at least Go's race detector no longer complains.
Test plan:
Fixes #24031.
[1] https://learn.microsoft.com/en-us/azure/developer/go/azure-sdk-core-concepts