Reputation: 1250
I found a weird behavior using a Lambda function in Amazon Web Services.
I'm using Node 4.3 and Mongoose 4.4.17
The idea is to test and play with the capabilities of Lambda.
I make a simple model and i store it in a Ec2 instance. The code works fine until i try to close the connection. I know, better practices say "Don't close you connection, let the pool handle." Well, this apply in a normal Application, but Lambda is a stateless function, so if i don't close the connection this keeps open, consuming resources. And this could be really bad when you have thousands of requests per second.
So, this is my code.
'use strict';
let mongoose = require('mongoose');
//I add this options, because this close my connections
//faster than the 30 min by default
let options = { server: { socketOptions: { keepAlive: 30000, connectTimeoutMS: 30000 } }};
let db = mongoose.createConnection('mongodb://myInternalServerEC2:27017/myDB', options);
let Schema = require('mongoose').Schema;
let TempSchema =new Schema({name:{type:String,required:true}});
//This is a copy paste from an another project,
//but i can remove, but i don't think this has nothing
//with my problem.
personSchema.set('autoIndex', false);
personSchema.index({name:1});
let tempDB = db.model('tempcol', TempSchema);
exports.handler = (event, context, callback) => {
tempDB.find(function (err, data) {
if (typeof(data) === 'object' && data.length === 0) {
data = null;
}
if (!err && data !== null) {
callback(null, data);
} else if (!err) {
error = new Error("No data found");
callback(error);
} else {
callback(err);
}
}).populate('_typeId');
};
This code Works without problems.
Now... lets try to close the connection. (Ha ha)
I use this in any case of the ifs, at the end of the if, after the if inside the find function, etc.
db.close();
callback(null, data);
mongoose.disconnect();
callback('Some error');
//This finish inside the find function
finish(db, function(){
callback(error, data);
});
// A finish function with a callback,
// so i can call the parent callback
function finish(db, cb){
db.close(function(){
cb();
});
}
In every single case. The Lambda function never returns an error, only returns NULL.
Anyone has some clue why this behavior in Lambda? In local mode, this behavior never happens to me before.
If i remove the close instruction, the lambda function returns data from my Mongo server
Thks in advance
Upvotes: 2
Views: 4055
Reputation: 1250
I found the problem.
The problem is the context. And the callbacks. I change the code to include the createConnection event inside the handler.
https://aws.amazon.com/es/blogs/compute/getting-nodejs-and-lambda-to-play-nicely/
This code works.
'use strict';
let mongoose = require('mongoose');
let options = { server: { socketOptions: { keepAlive: 30000, connectTimeoutMS: 30000 } }};
let Schema = require('mongoose').Schema;
let TempSchema =new Schema({name:{type:String,required:true}});
TempSchema.set('autoIndex', false);
TempSchema.index({name:1});
exports.handler = (event, context) => {
let db = mongoose.createConnection('mongodb://myInternalServerEC2:27017/myDB', options);
let tempDB = db.model('tempcol', TempSchema);
function closeBD(cbk){
console.log("Close BD");
db.close(function(){
cbk();
});
}
tempDB.find(function (err, data) {
if (typeof(data) === 'object' && data.length === 0) {
data = null;
}
if (!err && data !== null) {
context.succeed(data);
} else if (!err) {
let error = new Error("No data found");
context.fail(error);
} else {
context.fail(err);
}
closeBD(function(){
context.done();
});
});
};
Hope someone find this usefull.
Upvotes: 7