Meteor latency compensation and Date()

I have been working with shared methods for a while, but still cannot figure out their behaviour in some cases.

When I call a shared method, which inserts a document like this:

Meteor.methods({
  'method': function(){
     Posts.insert({
       'timestamp': new Date()
     });
  }
})

...will the latency compensation still work, considering that Date() will differ on the client and server, which means the server will send its own version to client anyway. If it does, is there any workaround or should we use insert methods with timestamps server-side only?

Upvotes: 3

Views: 74

Answers (1)

tyleha
tyleha

Reputation: 3429

Short answer, yes, latency compensation will work even with date inserts. But whatever date is inserted into Minimongo client-side will eventually be overwritten by the server.

The series of events looks something like this:

  1. (Client) The client runs its version of the method, inserting a Date into the Minimongo posts collection. Let's say the client thinks it is 04:31:03 UTC, when in reality it is 04:33:44 UTC. Regardless, now you have a document client-side with the an "incorrect" timestamp. This is latency compensation in action and this is OK - we aren't going to wait around for the server to finish inserting, we're going to render the UI immediately even if that UI is incorrect.
  2. (Server) Meanwhile, the server is told to execute the same insert. But the server knows the correct time, and inserts a document into Mongo with the time 04:33:44 UTC.
  3. (Client) Your client is presumably subscribed to the posts collection, and immediately upon the server's completion of the insert, your posts subscription observes a change to the collection and sends the document over DDP to the client.
  4. (Client) Minimongo merges this new incoming server posts document with its own collection. In the process, it overwrites the incorrect time with the correct, server-generated time. Any related UI will reactively update and reflect this change.

Kyll suggested a MeteorPad, so here's a very basic example. Click on the words "Click me to test timestamping" and you'll notice the millisecond display beneath it flash two times: the first time when the client updates with its own timestamp and the second time when the server returns with ITS timestamp. If you look at the client and server logs, you'll see this is true.

Got kinda long-winded, but hope this helps! If you need the server to trust and re-use the client-generated date, simply pass the Date object as a parameter to your method like

'method': function(date) { 
    check(date, Date);
    Posts.insert({timestamp: date});
}

However, you typically want the server to be the source of truth for your timestamps. You can never trust the client to know what time it really is!

Upvotes: 1

Related Questions