Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Document need for unique count names #66

Open
chmac opened this issue Sep 3, 2015 · 4 comments
Open

Document need for unique count names #66

chmac opened this issue Sep 3, 2015 · 4 comments
Labels

Comments

@chmac
Copy link

chmac commented Sep 3, 2015

I noticed in #43 that @boxofrox mentions the need to publish counts with a unique name. I didn't notice that in the docs (forgive me if I overlooked it). It didn't occur to me after reading the README that the counts would require a unique name per client to be unique per client. If that is the case, would be nice to mention it (or make it bolder if it's already there) in the docs.

Happy to submit a PR if you'd like one.

@tmeasday
Copy link
Member

tmeasday commented Sep 3, 2015

Sure thing.

@ubald
Copy link

ubald commented Sep 4, 2015

Wait... I realized that unfortunately the names had to be unique when listing groups and trying to show the number of items in each group. But reading @chmac 's comment I wonder, do names also have to be unique per client (considering they don't have access to the same counted items)?

@boxofrox
Copy link
Contributor

boxofrox commented Sep 5, 2015

@ubald, my mind's a bit hazy tonight, and I may be overlooking something here, so take what I say skeptically and verify it makes sense.

Currently, the documented way of publishing counts in the browser works through Meteor subscriptions. Using this mechanism, publish-counts avoids having to keep a server-side cache of all counters for every client. Instead, we use the Meteor.publish callback to create a closure for a new counter variable and wire it up to the calling client through the this instance of the Meteor.publish callback function. It just works.

So to answer your question, names don't need to be unique per client... normally. If one client has multiple counts, then each count for that client should have a unique name.

There is an edge case/bug where you subscribe to the exact same count twice and it doesn't matter that the names are the same because the counts are calculated with the exact same algorithm, so even though the record in the Counts collection is written more than once per update, the count still works out to the correct value.

Abnormally, you might want to pursue something like in #63 where a user wanted to use Counts.get on the server, too. (see related commented) In this case, the server side would need to expose the count variables hidden behind closures... probably through a global registry on the server... which would be used to store all counts for all clients. Names would have to be unique across clients to avoid collisions.

@chmac, the docs don't mention the need for unique names. You're welcome to submit a patch to add that.

It was likely overlooked for the fact that with many simple counts (e.g. Counts.publish(this, 'posts', Posts.find()); Counts.publish(this, 'comments', Comments.find());), it's fairly obvious that two counts with the same name could only provide one of those counts, not both.

Where it isn't so obvious, and the reason for the comment in #43, is when you have subscription parameters that reduce the result set of a subscription, and then a single client subscribes multiple times to the same subscription with different parameters.

// One client will view a page with three groups of posts, each group with
// a different category. That one client will subscribe three times to
// 'postsByCategory' and expects 3 unique counts, one for each column.
// Each 'name' in publish-counts has one value, so you must make three
// names for three values.

if (Meteor.isServer) {
  Meteor.publish('postsByCategory', function (category, limit) {
    Counts.publish(this, 'posts-by-' + category, Posts.find({ category: category }));
    if (limit)
      return Posts.find({ category: category });
    else
      return Posts.find({ category: category }, { limit: limit });
  });
}

if (Meteor.isClient) {
  Meteor.subscribe('postsByCategory', '#insects');
  Meteor.subscribe('postsByCategory', '#mammals');
  Meteor.subscribe('postsByCategory', '#birds');

  console.log(
    Counts.get('posts-by-#insects'),
    Counts.get('posts-by-#mammals'),
    Counts.get('posts-by-#birds')
  );
}

Sorry for the excessively long post.

@ubald
Copy link

ubald commented Sep 8, 2015

Thanks @boxofrox

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

4 participants