在我的Meteor应用程序中,我在observe
内创建了publish
,在某些条件下插入了一些新数据。关键是有时候我们有重复的订阅,竞争条件会导致我们复制插入的数据。
如果是not possible to have "singleton observers":
示例:
Meteor.publish("fortuneUpdate", function () {
var selector = {user: this.userId, seen:false};
DailyFortunes.find(selector).observe({
removed: function(doc, beforeIndex){
if(DailyFortunes.find(selector).count()<1)
createDailyFortune(this.userId);
}
});
}
此问题已从How cursor.observe works and how to avoid multiple instances running?
移至答案 0 :(得分:2)
According to Tom,目前不可能确保共享具有相同参数的订阅调用。 所以,如果你遇到了同样的问题,在观察者中创建了多余的数据,我建议你作为解决方法:
示例强>:
Collection.find(selector).observe({
removed: function(document){
try {
// Workaround to avoid race conditions > https://stackoverflow.com/q/13095647/599991
createNewDocument();
} catch (e) {
// XXX string parsing sucks, maybe
// https://jira.mongodb.org/browse/SERVER-3069 will get fixed one day
if (e.name !== 'MongoError') throw e;
var match = e.err.match(/^E11000 duplicate key error index: ([^ ]+)/);
if (!match) throw e;
//if match, just do nothing.
}
self.flush();
}
});
答案 1 :(得分:2)
这是一种奇怪的模式。你能分享一些示例代码吗?
一般来说,我或者期望在方法中看到突变,或者在服务器上设置observe
Meteor.startup()
。 (如果您运行多个服务器进程,后者是棘手的,但在多进程机制中还有很多其他事情。我们将有更好的模式。)
因为它可以是任意JS,所以每个订阅客户端必须运行一次发布函数。它可以记录新订阅,设置每个客户端服务器状态,或根据this.userId
或甚至随机源改变其行为。例如,考虑一个订阅,它将从DB集合中随机选择的10个文档返回给每个订阅的客户端!
因此,优化订阅相同数据集的许多客户的情况的地方是在DB查询层:如果一千个客户订阅了相同的数据库查询,我们将只运行一次基础查询。