混合原生Mongo和Meteor系列时的奇怪之处

时间:2014-08-06 15:55:26

标签: mongodb meteor

我有一个直接遍历Mongo集合的服务器方法(即不使用Meteor集合):

var db = MongoInternals.defaultRemoteCollectionDriver().mongo.db;

db.collection("dataRecords").find({}).each(...)

在每个()回调中,我使用不相关集合上的Meteor集合进行读取:

ReportDefs.findOne(...);

执行读取操作时,暂停执行该路径并开始处理下一条记录。这种情况一直在发生。同时,执行在一些暂停的路径上恢复,但这与新记录的处理重叠。结果很糟糕。

所以看起来findOne()在each()回调中不再是同步的吗?

有谁知道如何安全地混合原生Mongo和Meteor系列?我在处理大量记录时试图避免Meteor集合的开销。

2 个答案:

答案 0 :(得分:2)

尝试使用Meteor.bindEnvironment完成“每次回调”。问题来自于流星代码强烈依赖于“当前光纤”的存在(外观here for more details)。这就是findOne等例程的同步行为甚至可能的原因。因此,您需要提供正在运行的Fiber,但Meteor.bindEnvironment已经处理完毕。

有趣的是,因为 Meteor 总是用来警告用户这个问题,例如“流星代码必须始终在光纤内运行”。你没有得到这种类型的消息吗?

答案 1 :(得分:0)

我最终想出来了。如果你这样做

cursor.each()

和wait()在回调中的任何地方,下一个each()回调可以启动,所以你最终并行处理记录,服务器方法可以在一切完成之前返回。

解决方案是在回调中使用cursor.nextObject()来处理下一条记录,只有当你完成处理当前记录时。你应该将它包装在process.nextTick()中,否则你会继续深入到堆栈中。