CosmosClient initialization (BuildAndInitializeAsync/CreateAndInitializeAsync) with TokenCredential doesn't respect cancellation token
See original GitHub issueThe following code (or it’s alternative without the builder with CosmosClient/CreateAndInitializeAsync) doesn’t respect the cancellation token:
return new CosmosClientBuilder(cosmosDbUri, tokenCredential)
.WithConnectionModeDirect(enableTcpConnectionEndpointRediscovery: true)
.BuildAndInitializeAsync(new[] { (database, container) }, cancellationToken).GetAwaiter().GetResult()
.GetDatabase(c.Database)
.GetContainer(c.Container);
In order to reproduce you can use DefaultAzureCredential locally as it takes some time to find a working credential.
Expected behavior: immediate cancelation Actual behavior: cancelation after first token is returned or GetTokenAsync threw an exception SDK Version: 3.29.0 OS Version: Windows (doesn’t matter)
I found the bug in the following source file: Microsoft.Azure.Cosmos\src\Authorization\TokenCredentialCache.cs#191, method RefreshCachedTokenWithRetryHelperAsync
this.cachedAccessToken = await this.tokenCredential.GetTokenAsync(
requestContext: this.tokenRequestContext,
cancellationToken: default);
The cancelation token is not propagated to this call. Only if cancellation was requested just before the call, it will be cancelled.
This bug causes health issues in my Service Fabric service since SF’s RunAsync is not able to respond properly. I am creating my own TokenCredential wrapper in order to overcome this issue.
Issue Analytics
- State:
- Created a year ago
- Comments:10 (5 by maintainers)
Top GitHub Comments
Yes @ealsur, perfectly summarized!
Fair point on the try/catch, I completely missed it and you are right, the catch won’t work if there is a failure.
Let’s summarize this issue into 2 improvements:
Change the signature of this method to
async
andawait
the call toTask.WhenAll
: https://github.com/Azure/azure-cosmos-dotnet-v3/blob/master/Microsoft.Azure.Cosmos/src/CosmosClient.cs#L1345-L1363Make sure the calls to
this.tokenCredentialCache.GetTokensAsync
receivethis.cancellationToken
: https://github.com/Azure/azure-cosmos-dotnet-v3/blob/master/Microsoft.Azure.Cosmos/src/Authorization/TokenCredentialCache.cs#L191-L193