We are continuously addressing and improving the SDK, if possible, make sure the problem persist in the latest SDK version.
Describe the bug
A clear and concise description of what the bug is.
To Reproduce
1) Following this url for blazor setup : https://docs.microsoft.com/en-us/aspnet/core/blazor/get-started?view=aspnetcore-3.0&tabs=visual-studio
2) Create a Blazor Client project
3) Install nuget package - Install-Package Microsoft.Azure.Cosmos -Version 3.2.0
4) Run following code snippet in any btn handler click or may be startup
var client = new CosmosClient(Endpoint, key);
5) Blazor app will freeze and ultimately error out.
Expected behavior
Should be able to create a cosmos client and then do other operation afterwards
Actual behavior
Blazor app will freezes and nothing happens, have stop the debugging session
Environment summary
.NET Core SDK (reflecting any global.json):
Version: 3.0.100-rc1-014190
Commit: c4d43f672d
Runtime Environment:
OS Name: Windows
OS Version: 10.0.17134
OS Platform: Windows
RID: win10-x64
Base Path: C:\Program Files\dotnet\sdk\3.0.100-rc1-014190\
Host (useful for support):
Version: 3.0.0-rc1-19456-20
Commit: 8f5d7b1ba4
.NET Core SDKs installed:
2.0.2 [C:\Program Files\dotnet\sdk]
2.1.202 [C:\Program Files\dotnet\sdk]
2.1.502 [C:\Program Files\dotnet\sdk]
2.1.508 [C:\Program Files\dotnet\sdk]
2.1.509 [C:\Program Files\dotnet\sdk]
3.0.100-rc1-014190 [C:\Program Files\dotnet\sdk]
.NET Core runtimes installed:
Microsoft.AspNetCore.All 2.1.6 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All]
Microsoft.AspNetCore.All 2.1.12 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All]
Microsoft.AspNetCore.All 2.1.13 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All]
Microsoft.AspNetCore.App 2.1.6 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 2.1.12 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 2.1.13 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 3.0.0-rc1.19457.4 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.NETCore.App 2.0.0 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 2.0.9 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 2.1.6 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 2.1.12 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 2.1.13 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 3.0.0-rc1-19456-20 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.WindowsDesktop.App 3.0.0-rc1-19456-20 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
Additional context
Add any other context about the problem here (for example, complete stack traces or logs).
Hi @pkaushik23 ,
Any chance you can test it against the 3.1.1 release? I'm interesting if this is a recent regression or a bug that has always existed.
Hello @j82w i tested against 3.0.0, 3.1.1 and 3.2.0. All of them had the same behaviour. Thanks.
@pkaushik23 Can you share a snippet of how you are newing the CosmosClient during startup?
Hello @ealsur, please following:
https://github.com/pkaushik23/mycodeshares/blob/checkcosmosissue/CheckRefreshBlazor/Pages/Index.razor
void InitClient()
{
var cosmosClient = new CosmosClient("AccountEndpoint=your string");
}
@ealsur were you able to repro the issue ? thanks
Sorry for the delay @pkaushik23.
I believe your approach is incorrect. You need to be doing the same thing as the StringService.
Go to your Startup.cs, register the CosmosClient as Singleton, and then inject it and use it.
Creating the CosmosClient in a button handler is not really following any of the Performance Tips and potentially can create a lot of instances in memory.
See https://github.com/Azure/azure-cosmos-dotnet-v3/pull/981
Particularly:
Thanks @ealsur for the example code and your adivce.
Howevere there are few thing where in I am not sure if advised approach will help me. Please check following:
I have a requirement where in I want to work with multiple accounts in the same application. So injecting a client which can work with a single endpoint may not help me. You can think of a use case where in you have a button, on click of it, you ask user for connection string, thereafter you open that account in a tab.
About memory leakage, if I am using the .net constructs of "using", will that not mitigate that issue?
Please advice. Thanks.
If you need a service that generates instances of the CosmosClient based on some condition, then create such a service and register it as Singleton during Startup. Our recommendation is that instances should be kept and reused (https://docs.microsoft.com/en-us/azure/cosmos-db/performance-tips#sdk-usage).
Even if you wrap the CosmosClient in a using, which will Dispose of the memory, the other problem you have is that connections are not released immediately (https://aspnetmonsters.com/2016/08/2016-08-27-httpclientwrong/), so if you do that many times in a small slice of time, your application might end up consuming a lot of connections (that are still in TIME_WAIT) and depending on where you run the App (some hosting environments have limits to the # of connections), you might face socket starvation.
If creation CosmosClient instances is based on the click of a button, you need to make that process thread-safe and possibly use contention (for example, ConcurrentDictionary or locks), otherwise, bringing your app down is just a matter of a user clicking a button constantly.
Thanks again @ealsur for your answers, I will try to excute the ideas you advised. Mine was a blazor application hosted on client (Web Assembly), i assume the advise would be same for that hosting model too.
About having a singleton instance of service that gives me CosmosClient, the same should be followed as well used, when I have a api project? (this is an additonal question).
Thanks in advance
The approach for a Web API would be the same, I have recently answered a similar question here with some sample code 馃槃
@ealsur i think, i now understand what you meant, perhaps you meant registering a singleton service which has a collection (thread safe) which will maintain CosmosClient for each of the account I am trying to handle within my application (I want to work with multiple accounts in the same application my use case ). Please feel free to close the bug , if you think my interpretation is correct. Again, thanks lot for your suggestons. I appreciate.
If you need a service that generates instances of the CosmosClient based on some condition, then create such a service and register it as Singleton during Startup. Our recommendation is that instances should be kept and reused (https://docs.microsoft.com/en-us/azure/cosmos-db/performance-tips#sdk-usage).
Even if you wrap the CosmosClient in a using, which will Dispose of the memory, the other problem you have is that connections are not released immediately (https://aspnetmonsters.com/2016/08/2016-08-27-httpclientwrong/), so if you do that many times in a small slice of time, your application might end up consuming a lot of connections (that are still in TIME_WAIT) and depending on where you run the App (some hosting environments have limits to the # of connections), you might face socket starvation.
If creation CosmosClient instances is based on the click of a button, you need to make that process thread-safe and possibly use contention (for example, ConcurrentDictionary or locks), otherwise, bringing your app down is just a matter of a user clicking a button constantly.
Is problem of connections not releasing immediately, is relevant in .net core ?
https://docs.microsoft.com/en-us/aspnet/core/fundamentals/http-requests?view=aspnetcore-3.0&fbclid=IwAR1pALyvWdaHUZCF5tv2-J_zLq94OxroJk_OBOSc6XAaRDq7ZQH6ldF5fQU#httpclient-and-lifetime-management
It is, because that link only points at cases where you use IHttpClientFactory. If the code does a new HttpClient, then it can hit the connections issue, whether it runs on NET Core or NET Framework.
Most helpful comment
If you need a service that generates instances of the CosmosClient based on some condition, then create such a service and register it as Singleton during Startup. Our recommendation is that instances should be kept and reused (https://docs.microsoft.com/en-us/azure/cosmos-db/performance-tips#sdk-usage).
Even if you wrap the CosmosClient in a using, which will Dispose of the memory, the other problem you have is that connections are not released immediately (https://aspnetmonsters.com/2016/08/2016-08-27-httpclientwrong/), so if you do that many times in a small slice of time, your application might end up consuming a lot of connections (that are still in TIME_WAIT) and depending on where you run the App (some hosting environments have limits to the # of connections), you might face socket starvation.
If creation CosmosClient instances is based on the click of a button, you need to make that process thread-safe and possibly use contention (for example, ConcurrentDictionary or locks), otherwise, bringing your app down is just a matter of a user clicking a button constantly.