Reputation: 786
I am building a social community where a user is rewarded if someone upvotes/shares his/her answers. I also send a notification to the user when his/her answer has some interaction.
I have explained the flow though comments in the following code. The function post_event is exposed to the API and the flow begins from there.
var answerController = function(){
Emitter.call(this);
var self = this;
var continueWith = null;
var push_event = function(event, answerId, likerId, callback){
// check for data and prepare a bacth of queries
// has to be done like this coz mongoose doesn't (yet) support nModified, nMatched for update
var batch = Answer.collection.initializeOrderedBulkOp();
batch.find(query).upsert().updateOne(update);
batch.execute(function(err,result) {
if(err){
return callback(err);
}else{
return callback(null, result.nModified);
}
});
};
// exposed as an API call for yo/share/view
// calls push_event
var post_event = function(req,res, next){
//check for data in incoming request and pass it forward
push_event(event,answerId, likerId, function(err, num_updated_docs){
if(err){
return errors.api_error({code: 500, message: err, res: res, next: next});
}else{
if(num_updated_docs){
// create the calculateScore_args variable
self.emit('calculateScore',calculateScore_args);
res.status(200).send({message : 'success'}).end();
}else{
return errors.api_error({code: 401, message: 'event already exists for user', res: res, next: next});
}
}
});
};
var score = function(args){
var asyncTasks = [];
asyncTasks.push(function(cb){
//update user's score
// this is a cpu intensive function (does a small matrix multiplication)
})
asyncTasks.push(function(cb){
//update answer's score (user's score is a function of various answers)
// another CPU intensive call, calculates confidence interval ---> score
})
async.parallel(asyncTasks, function(err, results){
self.emit('notify', notifyData);
})
};
function notify(args){
// calls another controller which notifies the user(GCM) and inserts the notification into the DB
notification.AnswerEvent(args);
}
self.on('calculateScore', score);
self.on('notify',notify);
return {
post_event : post_event
}
};
Question : I would like to know if this is a feasible pattern for a system that would receive around 100-200 req/sec. It would be great if someone can advice me on other patters (like message queue) to follow. Also, what is the best way to debug event emitter code.
Thanks
Upvotes: 0
Views: 177
Reputation: 2253
Moving CPU intensive code out of the web server is the first and foremost way to prevent blocking.
A task queue is a very straightforward way to achieve this. With Ruby, I've used https://github.com/resque/resque with quite a bit of success in the past.
A node port such as https://github.com/taskrabbit/node-resque may be appropriate for your needs. You basically create a job, put it on a queue, and spin up some workers to chew off the required work.
Upvotes: 1