流星 - 检测无限循环
Meteor - detecting infinite loop
下面是用于计数事物的 Meteor 应用程序的一些代码(带有关联数据)的本质。计数可以链接在一起,以便一个可以增加另一个:
// The counting and linking code.
Meteor.methods({
'counts.increment'(countId) {
const count = Counts.findOne(countId);
Counts.update(countId,{ $inc: { count: 1 } })
Meteor.call('counts.check-links',count._id);
},
'counts.check-links'(countId){
var count = Counts.findOne(countId);
count.links.forEach(function (linkId) {
updated = false;
const link = Links.findOne(linkId);
const primary = Counts.findOne(link.primary);
const secondary = Counts.findOne(link.secondary);
if (primary.count == link.level) {
updated = true;
Counts.update(secondary._id, {$inc: {count: 1}});
}
if (updated) {
Meteor.call('counts.check-links',secondary._id);
}
})
}
})
// Some data...
Count: {
_id: 1,
value: 0,
name: A,
links: [3]
}
Count: {
_id: 2,
value: 0,
name: B,
links: [4]
}
Link: {
_id: 3,
primary: 1,
secondary: 2
}
Link: {
_id: 4,
primary: 2,
secondary: 1
}
因此,如果调用 Meteor.call('projects.increment',1)
,此代码将崩溃,因为每个计数都相互关联。检测这样的设置可能相当困难,因为可能有非常复杂的计数安排,并且链接也可能减少,设置为零,每 N 个计数等操作一次。 &C。不过,出于提出这个问题的目的,这无关紧要。
我想到的一种可能性是在 counts.check-links
中添加一个计数器,它将在任意数量的循环后停止执行,例如5. 据推测,为了防止篡改该计数器的值必须存储在数据库中并通过 Meteor 方法进行操作。它需要在任何 check-links
调用序列结束时重置。
我不确定这是否是最好的想法,或者如果是这样的话,怎样才是实施它的好方法,所以我很想知道是否有人有任何建议。
您可以创建一组已访问过的所有对象("Counts");所以如果你跟着一个link到这样一个对象,你可以避免再次处理它,从而运行进入无限递归。
编辑:例子
我不熟悉流星,所以如果它没有按预期工作,请原谅......这是所有允许对象引用指针的编程语言的常见问题,并且解决方案遵循类似的模式。
// The counting and linking code.
Meteor.methods({
...
'counts.check-links'(countId, alreadyVisited){
if (!alreadyVisited) alreadyVisited = {};
if (alreadyVisited[countId]) return;
alreadyVisited[countId] = true;
var count = Counts.findOne(countId);
count.links.forEach(function (linkId) {
updated = false;
const link = Links.findOne(linkId);
const primary = Counts.findOne(link.primary);
const secondary = Counts.findOne(link.secondary);
if (primary.count == link.level) {
updated = true;
Counts.update(secondary._id, {$inc: {count: 1}});
}
if (updated) {
Meteor.call('counts.check-links',secondary._id, alreadyVisited);
}
})
}
下面是用于计数事物的 Meteor 应用程序的一些代码(带有关联数据)的本质。计数可以链接在一起,以便一个可以增加另一个:
// The counting and linking code.
Meteor.methods({
'counts.increment'(countId) {
const count = Counts.findOne(countId);
Counts.update(countId,{ $inc: { count: 1 } })
Meteor.call('counts.check-links',count._id);
},
'counts.check-links'(countId){
var count = Counts.findOne(countId);
count.links.forEach(function (linkId) {
updated = false;
const link = Links.findOne(linkId);
const primary = Counts.findOne(link.primary);
const secondary = Counts.findOne(link.secondary);
if (primary.count == link.level) {
updated = true;
Counts.update(secondary._id, {$inc: {count: 1}});
}
if (updated) {
Meteor.call('counts.check-links',secondary._id);
}
})
}
})
// Some data...
Count: {
_id: 1,
value: 0,
name: A,
links: [3]
}
Count: {
_id: 2,
value: 0,
name: B,
links: [4]
}
Link: {
_id: 3,
primary: 1,
secondary: 2
}
Link: {
_id: 4,
primary: 2,
secondary: 1
}
因此,如果调用 Meteor.call('projects.increment',1)
,此代码将崩溃,因为每个计数都相互关联。检测这样的设置可能相当困难,因为可能有非常复杂的计数安排,并且链接也可能减少,设置为零,每 N 个计数等操作一次。 &C。不过,出于提出这个问题的目的,这无关紧要。
我想到的一种可能性是在 counts.check-links
中添加一个计数器,它将在任意数量的循环后停止执行,例如5. 据推测,为了防止篡改该计数器的值必须存储在数据库中并通过 Meteor 方法进行操作。它需要在任何 check-links
调用序列结束时重置。
我不确定这是否是最好的想法,或者如果是这样的话,怎样才是实施它的好方法,所以我很想知道是否有人有任何建议。
您可以创建一组已访问过的所有对象("Counts");所以如果你跟着一个link到这样一个对象,你可以避免再次处理它,从而运行进入无限递归。
编辑:例子 我不熟悉流星,所以如果它没有按预期工作,请原谅......这是所有允许对象引用指针的编程语言的常见问题,并且解决方案遵循类似的模式。
// The counting and linking code.
Meteor.methods({
...
'counts.check-links'(countId, alreadyVisited){
if (!alreadyVisited) alreadyVisited = {};
if (alreadyVisited[countId]) return;
alreadyVisited[countId] = true;
var count = Counts.findOne(countId);
count.links.forEach(function (linkId) {
updated = false;
const link = Links.findOne(linkId);
const primary = Counts.findOne(link.primary);
const secondary = Counts.findOne(link.secondary);
if (primary.count == link.level) {
updated = true;
Counts.update(secondary._id, {$inc: {count: 1}});
}
if (updated) {
Meteor.call('counts.check-links',secondary._id, alreadyVisited);
}
})
}