4

私はこのようなものを実装しようとしています:

/* We use the command pattern to encode actions in
   a 'command' object. This allows us to keep an audit trail
   and is required to support 'undo' in the client app. */
CommandQueue.insert(command);

/* Queuing a command should trigger its execution. We use
   an observer for this. */
CommandQueue
   .find({...})
   .observe({
       added: function(command) {
           /* While executing the action encoded by 'command'
              we usually want to insert objects into other collections. */
           OtherCollection.insert(...)
       }
   });

OtherCollection残念ながら、meteorはでトランザクションを実行している間、以前の状態を維持しているようですCommandQueue。に一時的に変更が加えられますOtherCollection。ただし、トランザクションがCommandQueue終了するとすぐに、の以前の状態OtherCollectionが復元され、変更が消えます。

なぜこれが起こっているのか考えはありますか?これは意図された動作ですか、それともバグですか?

4

2 に答える 2

2

これは予想される動作ですが、少し微妙であり、保証されていません(実装の詳細のみ)。

監視するコールバックは、コマンドがに挿入されるとすぐに起動しCommandQueueます。したがって、同じ呼び出しスタックの一部としてOtherCollection、メソッドの実行中に挿入が行われます。CommandQueue.insertこれは、OtherCollection挿入が挿入のローカル「シミュレーション」の一部と見なされCommandQueue、サーバーに送信されないことを意味します。サーバーはCommandQueue挿入を実行して結果を送り返します。その時点で、クライアントはシミュレーションの結果を破棄し、サーバーから送信された結果を適用して、OtherCollection変更を非表示にします。

これを行うためのより良い方法は、カスタムメソッドを作成することです。何かのようなもの:

Meteor.methods({
  auditedCommand: function (command) {
    CommandQueue.insert(command);

    var whatever = someProcessing(command)
    OtherCollection.insert(whatever);
  }
});

それで:

Meteor.call('auditedCommand', command);

これはクライアントにすぐに表示され(レイテンシー補正)、クライアントはにCommandQueue追加せずに挿入できないため、より安全OtherCollectionです。

編集:これはおそらく変更されます。追加されたコールバックは、実際にはCommandQueue.insertのローカルシミュレーションの一部と見なされるべきではありません。それが今のやり方です。とは言うものの、カスタムメソッドはおそらくこれに対してより良いアプローチであり、他の人がコマンドキューにコマンドを追加しても機能し、より安全です。

于 2013-01-11T23:03:26.987 に答える
0

監視動作についてはよくわかりませんが、サーバー側のallowメソッドを使用して同じことを実行しました。

CommandQueue.allow ({
  insert: function (userId, doc) {
    OtherCollection.insert(...);
    return (userId && doc.owner === userId);
  }
});

これは、このロジッククライアント側を配置するよりも安全です。

于 2013-01-11T04:08:32.497 に答える