0

これは、物を数える 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。ただし、この質問をする目的では、それは問題ではありません。

私が考えた 1 つの可能性はcounts.check-links、任意の数のループ (たとえば 5 回) の後に実行を停止するカウンターを追加することです。おそらく、このカウンターの値の改ざんを防ぐには、データベースに格納し、流星法。check-links一連の呼び出しの終了時にリセットする必要があります。

これが最善のアイデアなのか、それともどのように実装するのが良いのかはわかりません。誰か提案があれば知りたいです。

4

1 に答える 1

1

すでにアクセスしたすべてのオブジェクト (「カウント」) のセットを作成できます。したがって、そのようなオブジェクトへのリンクをたどると、そのオブジェクトを再度処理することを回避でき、無限再帰に陥ることになります。

編集:例私は流星に精通していないので、期待どおりに動作しない場合はご容赦ください...これは、オブジェクト参照のポインターを許可するすべてのプログラミング言語に共通の問題であり、解決策は同様の方法に従いますパターン。

// 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);
        }
    })
}
于 2017-04-24T10:04:24.557 に答える