Hi, I’ve built a sample chat application with Meteor 1.4.1. Here I’m trying to do a stress test by sending 10 messages per second. to monitor this I’m using Kadira APM.
Click here for the Trace for one send method.
In case link got expire here, I’m attaching the screenshot as well.
I can’t even user Meteor.defer or this.block here because I need to send the response to the client confirming whether the message is sent to the server or not.
send:function(msg){
let st = process.hrtime();
if (! this.userId) {
throw new Meteor.Error('error-not-authorized','User need to login', {method: "send"})
}
//check for the validation
NonEmptyString = Match.Where(function (x) {
check(x, String);
return x.length > 0;
});
check(msg, {
id: String,
msg: NonEmptyString,
rid: String,
lts: String
});
let u = Meteor.user()
let r = Rooms.findOne({_id: msg.rid})
if(! r){
throw new Meteor.Error("error-room-invalid", "Invalid Room id", msg.id);
}
//find the recepient user and check if he is online or not, if not send a push notification.
let ru = Meteor.users.findOne({$and: [{username: {$in: r.users}},{username: {$ne: u.username}}]})
if(! ru){
throw new Meteor.Error("error-invalid-recipient","No recipent user found", msg.id);
}
// TODO: Check for message limit
let record = {
_id: msg.id,
msg: msg.msg,
rid: r._id,
u: u.username,
ts: new Date(),
lts: msg.lts
}
let result = null;
try {
result = Chats.insert(record);
if(result){
//increase the msg counter
Rooms.update({_id: r._id}, {$set: {mc: r.mc+1}})
if((ru && ru.status) ? !ru.status.online : true){
Meteor.defer(function() {
Meteor.call('sendNotification',record,ru._id)
})
}
}
} catch (e) {
if (e.name === 'MongoError' && e.code === 11000)
result = record._id;
else
throw new Meteor.Error('error-500','Something went wrong', e)
}
let et = process.hrtime(st);
return {_id: result};
}
this.unblock() doesn’t stop you from getting a response back from a method, it just makes it so that other methods/publications can be processed while this one is running (with the magic of fibers).
isn’t this could be overhead to use in all the methods and publications. There could be some drawback of using this all the times.
Here I can use this for methods like send , read, and delivery report.
Because it can cause very hard to debug situations. The nice thing about the meteor calls now is that they work in serial. Unless you unblock off course.
I think that it’s best to use this.unblock in almost all situations, for both methods and publications. Qualia has a pretty sophisticated wrapper around all methods and publications, that makes this the default (and automatically does other things, like permissioning, rate limiting, debouncing, logging). We have yet to encounter a situation where this has caused issues.
If you don’t use this.unblock you will struggle to achieve acceptable performance. Unless you call this.unblock literally ZERO other methods or publications will be run until the current one completely finishes. For long running methods/publications that’s a total disaster.
Sorry to bump this… but trying to understand this.unblock and Meteor.defer. When you say:
Do you mean for just that client’s methods and publications? Or the entire server - thus all clients? It’s my understanding this is per client unblocking.