Assume a meteor server synchronously inserts 100 docs into collection A, then inserts 100 docs into collection B, and then inserts 1 doc into collection C.
Consider a client that is subscribed to all of these collections without restriction. Are there any insert ordering guarantees for the subscribed client? That is, would all A inserts be made at the client before any B inserts, thus matching the server insert order? Does it depend on the number of inserts to A?
This question stems from a stylized use of the above pattern and attempt to use the C insert to signal that both A and B have been fully updated. Unfortunately, it appears that only some of the A and B inserts are made prior to the C insert and I’m trying to understand how Meteor and DDP orders collection inserts for one or more collections.
Any insight is appreciated.
By default, DDP will send collection changes down the wire as they happen. Since MongoDB does not offer real transactions (see Perform Two Phase Commits for a possible workaround), you cannot guarantee in what order it will process inserts into your three collections.
So the non-determinism is in mongodb between the collection insert and the eventual oplog tail result? I had expected the synchronous collection insert monitors the mongo WriteResult() and does not return until the expected nInserted value.
I’d prefer to not have to modify the documents themselves to implement two-phase commits. Is there any other option?
In a non-replicated (i.e. primary not likely to change), non-sharded MongoDB deployment, with a single instance of Meteor server code, I would expect all A’s inserts to be performed in order, all B’s in order. I’m not certain that interleaving of inserts cannot occur, which means C’s insert can happen before A’s and B’s have completed.
So, you could use observe or observeChanges to watch for the appearance of the final documents in A and B, and only than insert C (although you probably wouldn’t need to, since you just determined the inserts have finished).