-
Notifications
You must be signed in to change notification settings - Fork 830
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
azidentity: sync.Cond.Wait is not being called in syncer #21151
Comments
Thanks for opening this! You're right, the condition is unused and therefore devolves to a mutex, so we may as well have just the mutex and simpler code.
We'll still try silent auth once for every
Currently we allow only one goroutine to authenticate with a credential instance at a time to avoid hitting a rate limit with redundant token requests. This enables sharing a credential instance--and thereby its token cache--with an arbitrary number of clients/goroutines.
I suppose it would be possible to synchronize goroutines more precisely by considering the parameters of the requested token. However, that would be much more complex than the current implementation and I imagine not much better for most applications. If the performance characteristics of the current implementation aren't acceptable for your application, I'd like to understand the bottlenecks through concrete perf data before jumping to a solution. |
Bug Report
github.com/Azure/azure-sdk-for-go/sdk/azidentity
latest
go version
:go version go1.20.5 linux/amd64
In
sync.go
implementation, we are using async.Cond
to coordinate multiple goroutines access to the token value:azure-sdk-for-go/sdk/azidentity/syncer.go
Lines 59 to 79 in 246ae74
But giving the
sync.Cond
is usingsync.Mutex
as lock, I don't think thes.cond.Wait
will be called at all:azure-sdk-for-go/sdk/azidentity/syncer.go
Lines 72 to 73 in 99ae59d
In cache miss case, the first goroutine enters the for-loop with obtaining
s.authing
andauth
status, then break the loop. However, this goroutine will still hold thes.cond.L
lock, as a result, other goroutines will be blocked in thes.cond.L.Lock()
line, so no further calls will reachs.cond.Wait
. We can confirm this behavior by checking the code path coverage from unit test.I think it depends. From syncer's unit test:
azure-sdk-for-go/sdk/azidentity/syncer_test.go
Lines 101 to 103 in 246ae74
It's expecting there will be N calls to the silent auth when there are N goroutines concurrently accessing the token. If this is the case, I think we can simplify the code to use a
sync.Mutex
only?If that's not the case, I think we need to move the
s.cond.L.Unlock
right outside the for loop so other goroutines can enter the for loop to wait, like this:But this will increase calls to silent auth though.
Check with code path coverage from unit test.
Anything we should know about your environment.
Follow up question:
We also want to confirm if the access control here is for limiting all access to the token, even the request option is different. We are using this library in a first party environment, therefore, we will need to request tokens for different tenants or different scopes at the same time.
The text was updated successfully, but these errors were encountered: