16

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?

THpubs
  • 7,154
  • 13
  • 60
  • 133

3 Answers3

10

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.

Mark B
  • 157,487
  • 23
  • 275
  • 266
  • 2
    Yes my current solution is removing db.close(). But is it ok to keep it like that? Any down sides? – THpubs Aug 22 '17 at 14:18
  • 3
    The downside is that the database will have to close connections itself after some timeout period. – Mark B Aug 22 '17 at 14:27
  • Ah. Then will there be a way to see whether it's closed or not and re-open? I think the same issue will arise if the connection gets closed by the db. – THpubs Aug 22 '17 at 14:42
  • Your DB probably won't close it faster than your Lambda function container would be destroyed due to inactivity, but I'd look at this if you want to add a check: https://stackoverflow.com/questions/17786080/how-to-check-if-mongodb-connection-is-alive-in-node-js – Mark B Aug 22 '17 at 15:12
0

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.

Gogu CelMare
  • 567
  • 3
  • 14
-4

May be try try-with-resource which closes the connection automatically.

Hari Rao
  • 2,580
  • 3
  • 19
  • 31
  • 1
    That doesn't solve the problem. He is already closing the connection successfully. The issue is that he's trying to reuse the connection after he is closing it. – Mark B Aug 22 '17 at 14:04