我有一个相当简单的Meteor应用程序。
我试图在我的列表中向大约3000名用户发送简报,但事情出错了。一组随机的用户收到了多封电子邮件(41到1之间)。
我注意到这种行为后立即关闭了服务器。大约1300封电子邮件被发送给210个用户。我想弄清楚发生了什么以及为什么。
以下是代码流程:
SendNow(客户端clode) - > SendNow(服务器方法) - > populateQue(服务器功能) - > processQue(服务器功能) - > sendEmails(服务器方法)
客户端代码:
'click .sendNow': function(){
/* code that forms data object */
Meteor.call('sendNow',data);
}
服务器代码: server / method.js
Meteor.methods({
'sendNow' : function(data){
if(userWithPermission()){
var done = populateQue(data);
if(done)
processQue();
return {'method':'sendNow','status':'ok'}
},
'sendEmails': function(data){
this.unblock();
var result = Mandrill.messages('send', data);// using external library
SentEmails.insert(data);//Save sent emails in a collection
}
});
服务器上的功能: server / utils.js
populateQue = function(data) {
/* code to get all users in to array */
MessageQue.remove();//Remove all documents from the Que
for (var i=0; i<users.length; i++) {
MessageQue.insert({userId: users[i]._id});
}
return true;
}
processQue = function(){
var messageQue = MessageQue.find({}).fetch();
for(i=0; i < messageQue.length; i++){
Meteor.call('sendEmails', data);
MessageQue.remove({_id: messageQue[i]._id});//Remove sent emails from the Que
}
}
我的第一次预感是MessageQue搞砸了,因为我在删除项目时processQue正在使用它,但我错了。经过一些测试后,我无法再次模拟这种行为
测试1:将Mandrill.message('send',data)
替换为Meteor._sleepForMs(1000);
- 在SentEmails
集合中只看到一封电子邮件/人。
测试2:将Mandrill置于测试模式(必须使用不同的API密钥)并使用几个日志语句重新运行代码。 - 在SentEMails
和Mandrill的界面中只能看到一个电子邮件/人。
它绝对不是外部库。它在我的代码或我理解流星工作的方式。
我注意到的一件事是通过另一个视图代码访问SentEmails集合时发生错误。我有一个视图,在客户端显示SentEmails,日期为过滤器。
这是错误:
Exception from sub sentEmailDocs id 9LTq6mMD4xNcre4YX Error: Exception while polling query { "collectionName":"sent_emails", "selector":{"date":{"$gt":"2015-07-09T05:00:00.000Z","$lt":"2015-07-11T05:00:00.000Z"}}, "options":{"transform":null,"sort":{"date":-1}} }: Runner error: Overflow sort stage buffered data usage of 33565660 bytes exceeds internal limit of 33554432 bytes这是吸烟枪吗?这会导致随机行为吗?
我已经进行了几次检查,以防止这种情况发生,但我对可能导致的原因和原因感到疑惑?我很乐意提供更多信息。在此先感谢谁愿意花几分钟时间。
答案 0 :(得分:0)
在黑暗中拍摄,但remove
方法接受一个对象,否则它不会做任何事情。 MessageQue.remove()
可能没有清除队列。您需要MessageQue.remove({})
。删除后执行if (MessageQue.find().count() > 0)...
测试理论。
如果你开始为队列设置一个单独的集合,并且我不是说这是一件坏事,我将_id
设置为用户身份。这样你就不可能两次向同一个人发送相同的消息。