I am trying to implement something like this:
/* 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(...)
}
});
Unfortunately it seems that meteor keeps the prior state of the OtherCollection while executing the transaction on CommandQueue. Changes are made temporarily to the OtherCollection. As soon as the transaction on CommandQueue finishes, the prior state of the OtherCollection will be restored, though, and our changes disappear.
Any ideas why this is happening? Is this intended behaviour or a bug?
This is the expected behavior, though it is a little subtle, and not guaranteed (just an implementation detail).
The callback to observe fires immediately when the command is inserted into
CommandQueue. So the insert toOtherCollectionhappens while theCommandQueue.insertmethod is running, as part of the same call stack. This means theOtherCollectioninsert is considered part of the local ‘simulation’ of theCommandQueueinsert, and is not sent to the server. The server runs theCommandQueueinsert and sends the result back, at which point the client discards the results of the simulation and applies the results sent from the server, making theOtherCollectionchange disappear.A better way to do this would be to write a custom method. Something like:
Then:
This will show up immediately on the client (latency compensation) and is more secure as clients can’t insert to
CommandQueuewithout also adding toOtherCollection.EDIT: this will probably change. The added callback shouldn’t really be considered part of the local simulation of CommandQueue.insert. Thats just the way it works now. That said, a custom method is probably still a better approach for this, it will work even if other people add commands to the command queue, and is more secure.