mondora / asteroid

An alternative client for a Meteor backend
MIT License
734 stars 101 forks source link

Unsubscribing and subscribing very quickly causes unexpected behavior #106

Open rafaelcorreiapoli opened 8 years ago

rafaelcorreiapoli commented 8 years ago

Hi, consider this code:

const b = function() {
1  const handler = asteroid.subscribe('pokemons')
2  const id = handler.id
3  asteroid.unsubscribe(id)
4  const handler2 = asteroid.subscribe('pokemons')
}

Until line 3 everything works as expected. I get all "added" messages and "removed" messages The problem is after resubscribing (on line 4) I don't get the "insert" messages again. I'm trying to understand how asteroid and ddp.js works inside to find clues about this behaviour and I think that is something related to the asynchronicity of unsub and sub

(Obviously the "b" function is hypothetical but something similar is happening on my App because of React's HMR)

rafaelcorreiapoli commented 8 years ago
const c = function() {
 const handler = asteroid.subscribe('pokemons')
 const id = handler.id
 asteroid.unsubscribe(id)
 setTimeout(() => {
  const handler2 = asteroid.subscribe('pokemons')
 }, 500) 
}

This makes it works as expected... so I think that the problem is related to asynchronicity

On meteor's own implementation, it works as expected

const m = function() {
const handler = Meteor.subscribe('pokemons')
handler.stop()
const handler2 = Meteor.subscribe('pokemons')
}

after calling m, I have the documents on the client provided by the "pokemons'' publication

clayne11 commented 7 years ago

This happens because when you unsub from a subscription, it doesn't actually get deleted from the subscription cache until the server replies with a nosub message.

https://github.com/mondora/asteroid/blob/master/src/base-mixins/subscriptions.js#L81-L86

IMO the subscription should be deleted immediately when you unsubscribe.

https://github.com/mondora/asteroid/blob/master/src/base-mixins/subscriptions.js#L63-L65

boldkhuu commented 7 years ago

I faced this problem and it's solved by below:

const c = function() {
  const handler = asteroid.subscribe('pokemons')
  const id = handler.id
  asteroid.unsubscribe(id)
  asteroid.subscriptions.cache.del(id) // deleting from cache synchronously
  const handler2 = asteroid.subscribe('pokemons')
}