Draft Mongo-GKE problem
Got error Cannot use a session that has ended. Seems like the app still getting request when closing the MongoDB connection.
Tried this forum but no luck
I use Nodejs with mongoose 5.8.1 and GKE as a infrastructure. Here’s the error stack
MongoError: Cannot use a session that has ended
at applySession (/app/node_modules/mongodb/lib/core/sessions.js:698:12)
at _command (/app/node_modules/mongodb/lib/core/wireprotocol/command.js:87:17)
at command (/app/node_modules/mongodb/lib/core/wireprotocol/command.js:28:5)
at Object.query (/app/node_modules/mongodb/lib/core/wireprotocol/query.js:70:3)
at Connection.query (/app/node_modules/mongodb/lib/cmap/connection.js:192:8)
at /app/node_modules/mongodb/lib/core/sdam/server.js:318:12
at Object.callback (/app/node_modules/mongodb/lib/cmap/connection_pool.js:347:7)
at processWaitQueue (/app/node_modules/mongodb/lib/cmap/connection_pool.js:470:23)
at /app/node_modules/mongodb/lib/cmap/connection_pool.js:263:28
at processTicksAndRejections (internal/process/task_queues.js:77:11)
What I tried:
- Await the close connection process when the app is killed, previously it’s using callback to close the connection. but even with await it takes around 6-7s for the connection to close so the app still receiving some request.
const gracefulExit = async (args) => {
console.log('RECEIVED GRACEFUL EXIT', args);
await mongoose.connection.close();
console.info('Mongoose disconnected on app termination');
process.exit(0);
};
- increasing the poolSize to handle more socket connection, smaller heartbeatFrequencyMS to reduce the time between server goes down and when Mongoose emits ‘disconnected’, and connectTimeoutMS to wait before killing a socket due to inactivity .
const options = {
useUnifiedTopology: !isLocal, // Needed for cloud run connection issues. Will throw a warning
useNewUrlParser: true,
useFindAndModify: false,
useCreateIndex: true,
poolSize: 10, // set the connection pool size
// serverSelectionTimeoutMS: 5000, // set the server selection timeout
heartbeatFrequencyMS: 5000, // set the heartbeat frequency
connectTimeoutMS: 10000, // set the connection timeout
};
- reconnecting when querying if it’s disconnected to MongoDB so if it’s disconnected when I try to query, it will reconnect to Mongo first.
try {
if (!filter) {
throw 'GET ONE: No filter supplied';
}
if(mongoose.connection.readyState !== 1) {
console.log("reconnecting...", mongoose.connection.readyState)
await connectDbAsync()
console.log("reconnected", mongoose.connection.readyState)
}
const result = await this.model.findOne(filter, fields, options);
return result;
} catch (e) {
console.error('GET ONE ERROR:', e);
throw e
}
but the error still persist. Any idea what’s wrong?
Thanks for your time!