fredrikekelund
fredrikekelund

Reputation: 2085

Keep two Meteor collections in sync

I want to keep a ServiceConfiguration collection in sync with a collection of settings. I've (nearly) accomplished this using observeChanges like so:

var handle = Settings.find().observeChanges({
    changed: function (id, post) {
        var insert = {};
        post.hostName && (insert.host = post.hostName);
        post.domainName && (insert.domain = post.domainName);

        ServiceConfiguration.configurations.update({service: "xmpp"}, insert);
    }
});

Meteor.publish("Settings", function() {
    this.onStop = function () {
        handle.stop();
    };

    return Settings.find();
});

The problem with this code however is that the publication's onStop method is called straight away, not when the client disconnects. The reason I'm using that callback is because the Meteor docs underline the importance of manually cancelling observeChanges handles, but if I cancel it this way, then I can't actually observe the changes to the collection. The code does however work fine if I don't stop() the handle.

So, can I not stop the handle or would that give me a memory leak? Or how should I go about keeping two Meteor collections in sync?

Upvotes: 1

Views: 147

Answers (2)

coreyb
coreyb

Reputation: 289

You can listen for updates to a collection using matb33:collection-hooks. This would be server side:

Settings.after.update(function(userId, doc, fieldNames, modifier, options){
    var insert = {};
    //...your logic
    ServiceConfiguration.configurations.update({service: "xmpp"}, insert);
});

Check out https://github.com/matb33/meteor-collection-hooks

Upvotes: 2

richsilv
richsilv

Reputation: 8013

TL/DR - yes, you're fine to remove it.

If I understand correctly, this is a situation in which multiple users can subscribe to the "Settings" publication, potentially change settings in the Settings collection, and you need to automatically propagate these to the ServiceConfiguration collection.

If this is the case then you should not be trying to stop the observer as it's a global construct designed to monitor all changes by any user. The case in which you need to stop an obsever on publication closure is when the observer is run from within the publish function, so there is a new one generated for every connected user. If you didn't stop the observer under those circumstances, the same user could repeatedly connect and disconnect and you'd be left with a potentially unlimited number of running observers and your app would die.

Here however, you would only ever have one observer, which runs independently of the number of subscribing clients. In addition, you can't stop it when any individual publication is stopped, as there will presumably still be other client subscribers who could continue to make changes.

In summary, it's fine to remove the onStop block. Let me know if that doesn't make sense.

Upvotes: 1

Related Questions