I have an ASP.Net MVC application using MongoDB as the database. The website and the database are on separate servers.
At the moment, I have a class that looks like this:
public class Mongo
{
private IMongoDatabase database;
public Mongo()
{
var client = new MongoClient("mongodb://username:password@ipaddress:port");
database = client.GetDatabase("MyDatabase");
}
public IMongoCollection<ApplicationUser> Users() { return database.GetCollection<ApplicationUser>("Users"); }
}
So to use it... (essentially in every request)
Mongo mon = new Mongo();
mon.Users.Find(........); // etc.
And this works ok - most of the time. On the odd occasion things appear to lock up and the database just times out until I restart the website. I get timeout errors where it's trying to connect to the database server.
While that's going on, the database server is confirmed up, and I'm able to connect to MongoDB from another mongo client without issue.
I'm conscious that there's no "close connection" thing going on in this - but there doesn't appear to be one to even call. So I wonder if it's something to do with too many connections being open and not being cleaned up properly.
Am I using MongoClient incorrectly? Is there something obvious that I should be doing to stop these timeouts?
This is the trace of the error I get:
[SocketException (0x274c): A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond ipaddress:port]
System.Net.Sockets.Socket.EndConnect(IAsyncResult asyncResult) +6768957
System.Threading.Tasks.TaskFactory`1.FromAsyncCoreLogic(IAsyncResult iar, Func`2 endFunction, Action`1 endAction, Task`1 promise, Boolean requiresSynchronization) +57
System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) +99
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) +58
System.Runtime.CompilerServices.TaskAwaiter.ValidateEnd(Task task) +25
MongoDB.Driver.Core.Connections.<ConnectAsync>d__7.MoveNext() +1542
System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) +99
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) +58
MongoDB.Driver.Core.Connections.<CreateStreamAsync>d__0.MoveNext() +345
System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) +99
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) +58
MongoDB.Driver.Core.Connections.<OpenAsyncHelper>d__1.MoveNext() +553
[MongoConnectionException: An exception occurred while opening a connection to the server.]
MongoDB.Driver.Core.Connections.<OpenAsyncHelper>d__1.MoveNext() +1372
System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) +99
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) +58
MongoDB.Driver.Core.Servers.<GetChannelAsync>d__0.MoveNext() +548
System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) +99
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) +58
System.Runtime.CompilerServices.TaskAwaiter.ValidateEnd(Task task) +25
MongoDB.Driver.Core.Operations.<ExecuteAsync>d__2.MoveNext() +639
System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) +99
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) +58
MongoDB.Driver.<ExecuteReadOperationAsync>d__0`1.MoveNext() +272
System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) +99
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) +58
MongoDB.Driver.<ExecuteReadOperation>d__35`1.MoveNext() +396
System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) +99
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) +58
MongoDB.Driver.<ToListAsync>d__14`1.MoveNext() +294
Of course, you should close the MongoClient instance, with the close() method (I had mentioned in my previous reply) at the closing of the application, to clear all the resources. This note is about using the code for creating the MongoClient object and its close() method.
Typically yes, it is a good practice to make MongoClient a singleton.
The MongoClient class is a class that allows for making Connections to MongoDB. The programmatically provided options take precedence over the URI options.
A connection pool is a cache of open, ready-to-use database connections maintained by the driver. Your application can seamlessly get connections from the pool, perform operations, and return connections back to the pool. Connection pools are thread-safe.
You are using MongoClient
incorrectly. As indicated in the docs
It is recommended to store a
MongoClient
instance in a global place, either as a static variable or in an IoC container with a singleton lifetime.
So you should rework your code to create a singleton MongoClient
instance and then use that throughout your program.
The reason is that MongoClient
maintains a pool of open connections that can be shared and reused for best performance.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With