I'm new to the database world (learing mongodb for node)
I'm a little bit confused about the client connection, I saw mongoDB connection doc example creating connection and close it but I'm not sure why they close it.
I'm thinking and asking myself if my end user will send to my server (nextjs) and the server will open a connection - at least the first time the server is up - to mongodb and fetch the data then send it back to the user.
in such a case should I close the connection (next users could use the same one)?
if no. which cases I have to close it ?
another confusing part to me about connection is caching :
I saw some code examples that do caching connection while I read that mongo has some sort of built in caching in RAM . is there a different ?
Is there any command or library in Node that would help me close all of the Redis connections?
I know I can track my connections and try to quit them inside process.on('exit', ...), yet I'd like to have a fallback method that closes all the connections first, before initiating new ones.
I have the following code in my app.js which runs on server start (npm start)
mongo.mongoConnect('connection_string', 'users').then((x) => {
console.log('Database connection successful');
app.listen(5000, () => console.log('Server started on port 5000'));
})
.catch(err => {
console.error(err.stack);
process.exit(1);
});
process.on('SIGINT', mongo.mongoDisconnect).on('SIGTERM', mongo.mongoDisconnect);
As you can see I open up SIGINT and SIGTERM for closing my connections upon process.exit
I've been reading a lot about how to deal with database connections in mongo and know that I should just invoke it once and have it across my application.
Does that mean that even after save() method when saving data to mongo followed by POST request, I should not be closing my connection? If I close it, how am I going to invoke it again since the connections happens on app start?
I'm asking it since in PHP I had the practice to always open and close my connection after querying MySql database.
Likewise, does it mean that the connection will close only on server shutdown in other words it will always be present since I do not want to shut down my node.js backend instance?
It is formally correct to open a connection, run a query, and then close the connection, but it is not a good practice, because opening a connection is an "expensive" operation and connections can be reused, which is much more efficient. The main restriction on an open connection is that it can only be used by 1 thread at a time. (More accurately, once a request is sent on a connection, no other requests can be sent on that connection until the response to that request is received.)
If your application is short lived or inherently single threaded, as may be the case when running as a "serverless" function, it may be acceptable to open and close a connection on each request.
While in theory it might be acceptable to open a single connection at the start of the program, keep a global reference to that connection, and reuse it, in practice there are common ways in which a connection becomes unusable that you would have to account for, and handling all the possibilities requires complex code. It gets even more complicated when, as is possible with MongoDB replica sets, you are actually connecting to more than one server and want to retry a command on a second server if the first one fails to respond.
That is why the standard and "best" practice is to use a "connection pool" to manage your database connections. A pool opens a set of network connections to the database, verifies and maintains their health, and dynamically assigns virtual database connections to actual network connections as needed. The pool is implemented in a library that will have received a lot of real world testing and is extremely likely to be better than anything you would write yourself. Connection pools have configuration options that would let you set any behavior you want, including opening a new connection for each request and closing it when done, but offer a wide range of performance enhancing capabilities, such a reusing connections and avoiding the overhead of creating them for each request.
This is why for MongoDB, the standard Node.js client already implements a connection pool. I do not know what mongo.mongoConnect in your code refers to; you said in the title that you are using mongoose but it uses connect, not mongoConnect to connect to the database. In general you should either be using the standard client or a JavaScript ORM library like mongoose. Either of them will take care of the connection management issues for you.
Refer to the documentation for the client/library you use for exactly the right way to use it. In general, you would initialize some kind of client object and store it globally before entering your main application handler. Then you would use this object to handle your database operations, and the object will transparently manage the underlying connections via the pool implementation. In this kind of setup, you would only close the connection when exiting the program, and usually the library takes care of that for you automatically, so you really never need to close the connection.
Thus, when using a MongoDB connection pool in NodeJS, you write your program basically the same way you would as if you just opened a connection at startup and then kept reusing it. The libraries take care of isolating you from all the problems that can arise from actually doing this. You do not need to, and in fact should not, close the connection after a database operation when using standard MongoDB NodeJS libraries.
Note that other connection pool implementations exist that do require you to close the connection. What you do with those pools is reserve (or "check out" or "open") a connection, use it, perhaps for multiple operations, and the release (or "check in" or "close") the connection when you are done. This is probably what you were doing in PHP. It is important to read and follow the documentation for the connection pool library you are using to make sure you are using it correctly.
This may not be the exact answer you are looking for, but it is not a good idea to open a new connection for every request and then close it. It is an overhead because it takes some time (even in milliseconds) to create a new connection.
Instead, you should create a pool of connections and use it in your app.
It's a good idea to close your mongo connection when your process dies or is stopped, but you should not need to close your mongoose connection after every successful query.
If you are instantiating a new mongo connection before each query you shouldn't need to be doing that either. You should just need to do that once when booting up your server.
you have two approaches
1) reopen a connection on every call using middle wares
2) you have to save your's query in node sometime later on execute all it onces
I'm using mongoose to maintain a connection with the database for my node.js app.
What I am doing is essentially open a connection the the database when the app starts and close the connection when it terminates. It's working fine and I have absolutely no issues querying and manipulating data, so no issues there.
I have a fair idea about how it works and how connections are pooled. However, I noticed that when the app is running, I randomly get an extra connection to my database - Multiple connections to DB
I'm using nodemon to track any file changes in my project but since the app closes every time nodemon cause it to restart, the connection should be destroyed because the app is closing, right?
Is it advised to close connections anywhere while the app is up and running and open it again as and when required? I haven't done that anywhere because from what I've read, it takes more time to open and close connections for every query. Could this be because I'm not disconnecting anywhere except for when the app closes?
I've seen a bunch of different ways of actually setting up a MongoDB connection:
I've seen some code where people don't use the open or error event
mongoose.connection.on('open', callback());
mongoose.connection.once('open', callback());
My take on it is:
If my app only connected to the database when it needs to use it, use (2)
If my app is constantly connected to the database ... it doesn't matter if I use (2) or (3)?
Which also raises the question, should my app maintain a persistent connection to the database (server and database running on same machine)?
Thanks for any help
You are correct that it doesn't matter if you use (2) or (3) when your application is constantly connected to the database.
As far as a persistent connection goes, the only cost of that is a tcp keepalive packet every once in a while. It's up to you to determine if the extra socket is worth not having to make a new connection for every call.