Reputation: 8162
In my lambda function, I tried to close the mongo connection as soon as I send a callback. But it has a problem.
db.close()
things work perfectly.I think lambda re-use the connection for all the functions because I open the connection in the top of the handler:
// Connect to database
mongoose.connect(process.env.DATABASE_URL);
const handleCreateUser = async (event, context, callback) => {
// eslint-disable-next-line no-param-reassign
context.callbackWaitsForEmptyEventLoop = false;
const data = JSON.parse(event.body);
const { user, userProfile } = data;
await createUser({ callback, user, userProfile });
};
Any idea what how to fix this? Do we really have to close the connection at this point?
Upvotes: 24
Views: 17840
Reputation: 4347
If you create the DB connection outside your handler, it will be setup in the Init
phase of the Lambda container. Then it can be used by one or more invocations (Invoke
phase). So closing the connection inside your handler will result in the following invocations having a non-usable, closed connection.
To properly close your connection (rather than awaiting the timeout), you can use a hook that triggers on container shutdown. As copied from here:
// SIGTERM Handler
process.on('SIGTERM', async () => {
console.info('[runtime] SIGTERM received');
console.info('[runtime] cleaning up');
// perform actual clean up work here.
await new Promise(resolve => setTimeout(resolve, 200));
console.info('[runtime] exiting');
process.exit(0)
});
Upvotes: 3
Reputation: 43
Lambda will executes your handleCreateUser function in each invocation but everything outside handleCreateUser will be executed only on cold start. Lambda will cache that values for further invocations and will not execute
mongoose.connect(process.env.DATABASE_URL);
in every invocation. So i think you should move this code in handleCreateUser function.
Upvotes: 4
Reputation: 815
My usage is Python but you will do this in your preferred language. Best solution for lambda, considering pay per time: Run this globally before lamba function (i do it in a config class)
if self.conn == None or self.conn.close == 1:
self.make_connection()
Up to you how you implement make_connection(). Do not use db.close() at all.
AWS calls loads your lambda function and runs you global functions once. After that at every call it ONLY RUNS the lambda which it keeps loaded for a while (from some tests 20min to 50min). The connection will be closed by the db driver on an internal timeout.
Advantages -you only open connection once in a long time saving you time for every lambda run.
Disadvantages - you hold on connection all the time lambda is in memory.
In my opinion it is worth it.
Upvotes: 1
Reputation: 200501
Either move the mongoose.connect
code inside the handler, or stop calling db.close()
. You currently have a single database connection being reused by multiple invocations of your Lambda function, but you are closing it after the first invocation completes.
Upvotes: 12