Simon Frey
Simon Frey

Reputation: 2949

Keep MongoDB connection open in serverless framework

I want to access a MongoDB from within a AWS lambda function deployed with the serverless framework (serverless.com)

There is an example by the framework on how they open it (https://github.com/serverless/examples/blob/master/aws-node-rest-api-mongodb/handler.js)

But if I understand the code correctly they open and close the connection for every request (relevant code of the example):

const mongoString = ''; // MongoDB Url

const dbExecute = (db, fn) => db.then(fn).finally(() => db.close());
function dbConnectAndExecute(dbUrl, fn) {
  return dbExecute(mongoose.connect(dbUrl, { useMongoClient: true }), fn);
}

module.exports.createUser = (event, context, callback) => {
     dbConnectAndExecute(mongoString, () => (
       user
       .save()
       .then(() => callback(null, {
       statusCode: 200,
       body: JSON.stringify({ id: user.id }),
      }))
      .catch(err => callback(null, createErrorResponse(err.statusCode, err.message)))
    ));
};

Is my assumption wrong and the connection is staying alive? If not, how would a correct pattern for keeping the connection open look like. I know that in AWS lambda there can be a global state, but apparently the serverless framework is removing everything after a single run as no state I set globally is persisted.

Upvotes: 0

Views: 796

Answers (1)

Gareth McCumskey
Gareth McCumskey

Reputation: 1540

If you want the connection to remain after for subsequent requests to teh warmed Lambda function, you should open the connection outside of the Lambda function itself, within the same scope as the const's you declare at the top of your example. The Serverless Framework is not the one closing anything, this is a feature of Lambda itself.

In addition, you are using a function called, dbConnectAndExecute, where it would probably be more useful to connect outside the function and then execute within; i.e. break up that function. This way your connection remains open but the execution is discarded after the Lambda executes.

One word of caution. Watch out for too many open connections on your MongoDB cluster. This is one of the reasons I prefer to use a service like DynamoDB where connections just don't exist; everything is performed over an API call. If you have 1000 simultaneously executing Lambda functions, each will have its own connection and may cause failure in queries later.

Upvotes: 1

Related Questions