Closed levalencia closed 5 years ago
Ok I figured it out.
Cosmonaut in the CosmosStore constructor will open the connection to the database and also create the database and the collection if they don't exist. Those calls are in the constructor and they are synchronised with .GetAwaiter().GetResult()
.
This should not be a problem in most cases, but in your case it is because you are initialising the CosmosStore in the Controller. The controller is part of a synchronisation context, almost like the UI thread in WinForm apps. They are known to deadlock if you synchronise an async call in them.
I tested it with a DI framework like Unity and Ninject and it is working fine if you inject it. Here is a tutorial by Microsoft on how to use dependency injection in Web API 2 with Unity. https://docs.microsoft.com/en-us/aspnet/web-api/overview/advanced/dependency-injection
To test that this was the problem I simply created a singleton and I initialised it on the Global.asax.cs.
This is NOT recommended at all, because it's untestable. You should use dependency injection, I just wanted to make sure that the deadlock was the problem.
Let me know if that helped.
can you please post the singleton class in text; so I dont have to type it all
Sure. Here you go:
public sealed class CosmosStoreHolder
{
private static CosmosStoreHolder instance = null;
private static readonly object padlock = new object();
public ICosmosStore<TestUser> CosmosStore { get; }
CosmosStoreHolder()
{
CosmosStore = new CosmosStore<TestUser>(new CosmosStoreSettings("localdb", "https://localhost:8081", "C2y6yDjf5/R+ob0N8A7Cgv30VRDJIWEHLM+4QDU5DE2nQ9nDuVTqobD4b8mGGyPMbIZnqyMsEcaGQy67XIw/Jw==",
settings =>
{
settings.ConnectionPolicy = new ConnectionPolicy
{ ConnectionMode = ConnectionMode.Direct, ConnectionProtocol = Protocol.Tcp };
}));
}
public static CosmosStoreHolder Instance
{
get
{
lock (padlock)
{
if (instance == null)
{
instance = new CosmosStoreHolder();
}
return instance;
}
}
}
}
btw; it would be nice if you can put in the documentation how to use it with Unity as well; as I dont have experience with DI, then that will make implementation straigh tforward
Hi Nick
Still the same problem, when remote debugging, the code hangs on the lock statement on the singleton forever and never steps inside.
Are you initialising the CosmosStores in the Application_Start() method as shown at the picture above?
lol, no, I didnt think that was needed because the picture shows that variable as not used anywhere else; but I will add it and try it again this afternoon
Haha that’s the whole point. Initialising the CosmosStore outside the controller which is part of the “bad” synchronisation context.
thank you for the help!
I followed the documentation as stated, and when I try to create a ICosmosStore to get information from CosmosDB, I got webapi timeouts, when I attached the debugger, I noticed the problem is not in the webapi, but apparently something in the cosmonaut library
My code is very simple>