Javascript 流星探测无限环

Javascript 流星探测无限环,javascript,meteor,halting-problem,Javascript,Meteor,Halting Problem,下面是Meteor计数应用程序的一些相关数据代码的精髓。计数可以链接在一起,以便一个可以增加另一个: // The counting and linking code. Meteor.methods({ 'counts.increment'(countId) { const count = Counts.findOne(countId); Counts.update(countId,{ $inc: { count: 1 } }) Meteo

下面是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运行一次&C为了问这个不重要的问题

我想到的一种可能性是在counts.check-links中添加一个计数器,它将在任意数量的循环后停止执行,例如5。据推测,为了防止篡改,该计数器的值必须存储在数据库中,并通过Meteor方法进行操作。它需要在任何检查链接调用序列结束时重置


我不确定这是否是最好的主意,或者这是否是一个很好的实现方法,因此我想知道是否有人有任何建议。

您可以创建一组已访问的所有对象计数;因此,如果遵循指向此类对象的链接,可以避免再次处理它,从而陷入无限递归

编辑:示例 我不熟悉meteor,所以如果它没有按预期工作,请原谅。。。但是,对于所有允许对象引用指针的编程语言来说,这是一个常见的问题,解决方案遵循类似的模式

// 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);
        }
    })
}

请确保验证您的服务器方法或其超级容易伪造此方法调用或执行一些nosql注入。服务器仅发布属于登录用户的数据,并且方法调用还检查是否正在对登录用户拥有的数据执行操作,我应该补充一点,在实际应用程序中也会检查所有Meteor.method参数-我在这里的示例中省略了这类内容。谢谢,我会尝试一下。想必最后应该清空else块中的alreadyVisited,因为如果没有更新任何内容,那么就不需要检查进一步的链接。看起来就是这样。为了安全起见,我将其存储在数据库中,以便应用一些检查,例如登录用户,而不是在方法中创建。否则我就用你放的东西了。