finer-grained reactivity for nested objects #2254
Comments
Yeah, this is a bug in the minimongo implementation of observeChanges with var X = new Package.minimongo.LocalCollection;
var id = "asdf";
X.insert({_id: id, foo: {bar: 123}});
X.find(id, {fields: {'foo.bar': 1}}).observeChanges({
changed: function (id, fields) {
throw Error("but nothing changed!");
}
});
X.update(id, {$set: {'foo.baz': 456}}); The problem is that Probably the projection needs to be applied before the diff rather than after. Might be tricky though because some parts of the code rely on the fact that the elements of |
…o's changed event. This change actually introduces another layer of projections before diffing, in addition to more projection after the diffing, on the result. I didn't figure out why, but the tests fail if you remove either of them. Adds tests. Fixes #2254.
…o's changed event. This change actually introduces another layer of projections before diffing, in addition to more projection after the diffing, on the result. I didn't figure out why, but the tests fail if you remove either of them. Adds tests. Fixes #2254.
This fails on both server and client. This is also related to #2254.
Projection functions act on *documents*, not the diffs that are passed to changed callbacks. For example, a projection `{'a.b': 1}` applied to the *document* `{a: undefined}` will result in `{}`, but the *diff* of `{a: undefined}` on a query with that projection should still result in a `changed` callback with that diff being invoked. Refactor various parts of minimongo to always have a projectionFn for each observed query (perhaps a trivial one). Pass the projection into _diffQueryChanges so that it can apply the projection *before* taking the diff, in the two cases in Minimongo which use _diffQueryChanges instead of direct application. (We could instead make the query's results and resultsSnapshot be projected, but Minimongo currently relies on the fact that these data structures alias the documents stored in the collection.) Stop applying the projection to the diffs in changed via wrapCallback. (We could still use wrapCallback to apply the projection for added/addedBefore calls, but it seems more consistent to use the same mechanisms for added that we use for changed. Fixes #3800. Fixes #2254. Fixes #3571.
Turned out this was related to #3571. Fixed! |
This is awesome! I can't wait to start using this functionality to optimize my helpers. |
Wow yes that is awesome! Can't wait for this next release. |
Great work, should help to make Blaze predictable in performance. |
Whoa! Does this mean nested fields have fine-grained reactivity now?? |
Well, it depends what you mean by that. |
Meteor release notes: http://info.meteor.com/blog/meteor-104-mongo-cordova-template-subscriptions https://github.com/meteor/meteor/blob/release/METEOR@1.0.4.2/History.md Important performance improvements included in this release: * If the oplog observe driver gets too far behind in processing the oplog, skip entries and re-poll queries instead of trying to keep up. meteor/meteor#2668 * Optimize common cases faced by the "crossbar" data structure (used by oplog tailing and DDP method write tracking). meteor/meteor#3697 * The oplog observe driver recovers from failed attempts to apply the modifier from the oplog (eg, because of empty field names). * Avoid unnecessary work while paused in minimongo. * Fix bugs related to observing queries with field filters: changed callbacks should not trigger unless a field in the filter has changed, and changed callbacks need to trigger when a parent of an included field is unset. meteor/meteor#2254 There are also API improvements which can lead to more efficient/less mistake-prone subscriptions and observe. We'll migrate to these new APIs in the next few commits. Change-Id: I58e464750a03d9cfedfa7f07c9e25e8a6460fcde
Template.hello.helpers({
user: function() {
return Meteor.users.findOne(Meteor.userId(), {fields: {"game.blah":1}})
}
})
If anything in Meteor.user().game changes then it invalidates this helper even though the fields specify that it only uses Meteor.user().game.blah. So if Meteor.user().var is updated then this helper will re-run.
https://github.com/dan335/fieldtest
http://fieldtest.meteor.com/
https://groups.google.com/forum/#!topic/meteor-talk/zg2cElH-Aqw
The text was updated successfully, but these errors were encountered: