We had some trouble with the automatic reconnect in Mongoose. In particular, the available options reconnectTries
and reconnectInterval
are applied when another HTTP request came in, not after the connection dropped (as I would have expected). This is the solution I came up with (basically adapted and extended from this:
-
Keep
reconnectTries
andreconnectInterval
low (but they don't really matter much in this solution anyway). -
Use something like the following for connecting to the database:
// Database connection
const mongoose = require("mongoose")
const connect = async () => {
try {
// Take URL from config and add options
await mongoose.connect("mongodb://localhost:27017/mydatabase")
} catch(error) {
console.log("Error connecting to database, reconnect in a few seconds...")
}
}
// Connect immediately on startup
connect()
const db = mongoose.connection
db.on("error", () => {
mongoose.disconnect()
})
db.on("connected", () => {
console.log("Connected to database")
})
db.on("disconnected", () => {
setTimeout(connect, 5000)
})
This tries to reconnect to the database after 5 seconds. On the server, we shouldn't need a slowdown of reconnect tries because we want the server to connect to the database soon after it is back up.
- Optional: Add a middleware that checks the database connection before routes (that depend on the database) are accessed. When the database is not connected, we can just return a database access error immediately.
const { DatabaseAccessError } = require("./errors")
app.use((req, res, next) => {
if (db.readyState === 1) {
next()
} else {
// No connection to database, return error
next(new DatabaseAccessError())
}
})
Let me know if you have any improvements!