Trying to understand collection updates on client-side vs server-side


#1

I read @sacha’s blog post about client-side collection operations (and using allow/deny), vs. using Meteor methods on the server to handle collection updates.

One thing I don’t understand:

Isn’t the whole point of doing inserts/updates on the client side so that the user immediately sees a change in their browser, even if the server-side operation takes a few seconds? If something like an upvote is carried out via a server method call, if there’s network latency, couldn’t it potentially be a handful of seconds before the user sees their thumbs up?


#2

Methods have two parts:

  1. The server side version - the real API, doing real changes to your database
  2. The client side version - “simulating” changes to your database, but only on the client.

Usually, these versions are the same - if you put your methods in a shared directory. This is how the idea of “latency compensation” works.

However, you can have completely different “stubs” on the client:

For example,
in client/dummy.js:

var myCollection = new Mongo.Collection('mycoll');
Tracker.autorun(function(){ console.log(myCollection.find().fetch())});
Meteor.methods({
  dummy: function(){
    myCollection.insert({value: "this is only a simulation side-effect."});
  }
});

in server/dummy.js:

var Future = Npm.require('fibers/future');
var myCollection = new Mongo.Collection('mycoll');
Meteor.methods({
  dummy: function(){
    var fut = new Future();
    Meteor.setTimeout(function(){
      fut.return(null, true);
    }, 10000);
    fut.wait();  //wait 10seconds
    myCollection.insert({value: "this is the canonical insert"});
  }
});

this would produce:

Meteor.call('dummy');
// immediately, the client-side stub runs, and produces the side-effect - an insert into "myCollection"
[{value: "this is only a simulation side-effect."}]
// after 10 seconds, the server responds with the finalised changes - in this case the client side changes are rolled back, in favour of the servers version.
[{value: "this is the canonical insert"}]

The final tower to climb - is to understand that “myCollection.insert/update/remove” is actually implemented as a Meteor.method. - In your browser console, type in Meteor.connection._methodHandlers and take a look at what’s there.


#3

I think I get it. So if I wanted to have it so clicking a thumbs up icon immediately added to the “like” count, I need a client-side method definition that increases the “like” count by 1, and a server-side method by the same name that actually updates the “like” count in the database?


#4

Yes - they could be separate pieces of code.

Or, if it’s just a simple update, just put your Meteor.methods in a directory shared by client and server, and it will work as a client and server version.