Possibly naive question about subscription changes


#1

Having a bit of an issue with subscriptions and understanding when data is added/removed from the client. I have a stops subscription which sends a bunch of data to the user based on their nearest 10 bus stops, calculated reactively based on position. For each stop, I compute the next departure, which is unfortunately a somewhat expensive calculation. So I’d like to minimize how many times it happens.

My app subscribes to the initial 10 stops based on either a default position or undefined, in which case the first 10 stops in the list are sent. This happens fine, and the next departures are computed.

Then position data arrives and the client sends another subscribe, this time based on the new position. I then, for a while, have 20 stops in my collection–the first 10 from the list of stops, and the next 10 sorted by proximity to the position. This creates several issues.

First, the next departure calculation runs at least 20 times. Since this is expensive, I’d rather not do this. It also lags out the page and renders everything unresponsive.

Next, ready() on the handle seems to be inaccurate. This triggers the next departure calculation to run even though the data necessary to run it isn’t entirely available, thus causing necessary reruns.

So, questions:

  1. If I subscribe to a publication, then subscribe again, is my original subscription stopped or do I need to stop it myself? IOW, will I still have the data from the previous subscription in my local collections, or will it get removed/updated when the subscription changes? So if I Meteor.subscribe("stops", position1) then Meteor.subscribe("stops", position2), do I just have position2’s stops in the database, or do I have them both unless I explicitly stop the subscription to position1?

  2. Is there some way to manually clear collections on my client without propagating those deletions to the server? I don’t want users deleting my list of bus stops, but there does seem to be a time when there are 20 rather than 10 records in the subscription, which causes scripts to lag out and become unresponsive.

Thanks.


#2

Using the Meteor.subscribe stop callback would seem to be what you want to do:

stop()
Cancel the subscription. This will typically result in the server directing the client to remove the subscription's data from the client's cache.

#3

Are your Meteor.subscribe("stops", position1) and Meteor.subscribe("stops", position2) called inside an autorun? Inside an Iron Router hook?


#4

So you explicitly have to stop subscriptions in order to not keep their data? Got it, I guess iron:router and friends do this automatically for me so I take it for granted.

So there does seem to be a point, between calling stop() and the new subscription, where the data isn’t removed from the client’s cache. Is stop() synchronous, or is there some other way to know that it has removed all cached data?


#5

Hmm - never used this, so I don’t know if it’s synchronous. However, you can supply an onStop callback, so I guess that will be safe whatever (and it may even be a hint that it’s asynchronous).


#6

Things to know when updating your subscription from autorun (or from most Iron Router hooks):


#7

Ah, caught it. I had an old subscription lingering in my router, left over from when I refactored to creating the subscription in my template instance. So that was keeping old documents around, adding extra computations and making everything laggier.