Why does withTracker() unsubscribe right after subscribing?

I used Meteor Dev Tools to analyze DDP communications between my React frontend and my backend. I noticed that every time a withTracker() computation re-runs and re-subscribes to an existing subscription, the subscription of the previous run will be unsubscribed (by sending UNSUB right after SUB).

If I call Meteor.subscribe() directly using the browser console, however, this does not happen.

So I am wondering why withTracker() unsubs the subscription. Is this necessary to avoid that multiple subs from the same component stay active?

I am asking this because I am developing my own DDP client and want to mimick the correct behavior. The DDP docs are somewhat limited.

Also, I am wondering if this is actually a behavior of withTracker() or some magic that Tracker does in the background, in combination with subscribe().

1 Like

Ok, after investigating the code of subscribe()

once more, I think I understand what happens:

  • If a (Tracker) computation becomes invalidated, all existing subscriptions are being “deactivated” (inactive = true)
  • If there is a subscribe() inside the computation that has exactly the same name and parameters, the subscription is being reactivated (inactive = false). This prevents that it is being re-run or unsubbed.
  • If there is a subscribe() with the same name, but different parameters, a new subscription is created. The old one (with the same name) will be unsubbed onAfterFlush(), i.e. after the new one has been subbed.
  • If there is no subscribe() with the same name at all, the existing sub will just be unsubbed without a recplacement.

So, to answer my own question: This is default behavior of Tracker and ensures that a) there is exactly one subscription with the same name per computation and b) there can be multiple subscriptions with the same name in different computations.

1 Like

My remaining question here is: What does the server expect if the WebSocket connection breaks up at some point of time, e.g. because of an unstable mobile connection?

Will it purge all subscriptions automatically, or does it still expect that the same client would unsub them after re-subbing to them on re-connect?

I’m not sure but this issue could be related: Double subscriptions when using useTracker in lazy components · Issue #324 · meteor/react-packages · GitHub

All of this looks right. The most recent version of withTracker (and useTracker) patched a problem around exactly that “magic” behavior.

There’s even a set of really old tests to validate all that:

1 Like

I still have to look in to this particular issue - but I don’t know if it’s been tested since the most recent release.

1 Like

Thanks for your response and confirming my observations!

1 Like

I don’t know what happens on the server side, but there is a reconnect event (distinct from connect) you can listen for on the client side, to display a “attempting reconnect in {XXX} seconds”, so there’s definitely some kind of consideration for this.

Thanks, but I am actually using a DDP library in Unity, so this would not work. Currently, I am re-examining the whole DDP communication handshakes, because I am facing a weird issue with dropped RESULT messages once I login after a connection breakup (unstable mobile connections):

It’s a phenomenon that mainly appears on Android devices. The login method works, but sometimes it won’t send RESULT back, only UPDATED. I have no clue so far what causes this behavior. It doesn’t happen in the regular Meteor web frontend. I can see no reason why the server should only send one of these acknowledgements. The DDP docs are pretty vage.