簡體   English   中英

流星探測無限循環

[英]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操作一次。 &C。 但是,出於提出這個問題的目的,這並不重要。

我想到的一種可能性是在counts.check-links添加一個計數器,該計數器將在任意數量的循環(例如5)后停止執行。大概是為了防止篡改該計數器的值,必須將其存儲在數據庫中並通過流星方法采取行動。 check-links的任何調用序列結束時都需要將其重置。

我不確定這是否是最好的主意,或者是否可能是實現它的好方法,所以我很想知道是否有人提出任何建議。

您可以創建一組已經訪問過的所有對象(“計數”); 因此,如果您跟蹤到此類對象的鏈接,則可以避免再次處理它,從而遇到無限遞歸。

編輯:示例我不熟悉流星,因此,如果它不能按預期工作,請原諒...這是所有允許對象引用指針的編程語言的常見問題,但是解決方案遵循類似的原則圖案。

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM