Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to properly close the database connection in a lambda function?

In my lambda function, I tried to close the mongo connection as soon as I send a callback. But it has a problem.

  • When I send a request, the function performs its duties, send the callback and close the database connection.
  • When the second request is sent, the function times out.
  • When I remove the 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?

like image 520
THpubs Avatar asked Aug 22 '17 00:08

THpubs


3 Answers

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.

like image 129
Mark B Avatar answered Oct 23 '22 18:10

Mark B


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.

like image 2
Dirgh Patel Avatar answered Oct 23 '22 17:10

Dirgh Patel


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.

like image 1
Gogu CelMare Avatar answered Oct 23 '22 18:10

Gogu CelMare