Meteor-Community-Packages / meteor-timesync

NTP-style time synchronization between server and client, and facilities to use server time reactively in Meteor applications.
https://packosphere.com/mizzao/timesync
MIT License
118 stars 36 forks source link

Weird issue while getting server time at client side #8

Closed aashuagg closed 9 years ago

aashuagg commented 10 years ago

Hi,

I have a specific requirement to get server time at client side, to correctly filter my collection data irrespective of individual browser time.

This package fulfills my requirement, but I am facing a weird issue while using it.

  1. Since I am using serverTime to filter the collection data and this package functions run in reactive context, serverTime keeps on changing at client side but I dont want to make serverTime reactive (as it results in running the mongo queries infinitely). So I used Deps.nonreactive to get serverTime on request basis:
var serverTime = Deps.nonreactive(function(){
            return TimeSync.serverTime();
        });

After this I am using it in my query:

Event.find({'startDate': {$gte: new Date(serverTime)}});

Everything works fine so far. Now I am facing weird issue, I noticed that sometimes serverTime variable have a value (i.e. time in milliseconds) while sometimes its just undefined which breaks my query on client side and it happens more often if I am using serverTime variable in the query, which means if I run query like Event.find({'startDate': {$gte: new Date()}});, most of the times serverTime variable has value. But If I am using it in query, this variable is always undefined.

I am not able to understand if I am doing something wrong or this is an issue with package.

Note. i am fetching serverTime and running query in a helper method and I already have data at client side through subscribe.

Thanks, Aashu

mizzao commented 10 years ago

You are probably trying to get the server time before the sync has taken place. You can use the TimeSync.isSynced() reactive variable to determine that a sync has taken place, then use Deps.nonreactive to get the current server time.

By the way, why are you filtering by time on the client? Why don't you just filter on the server, which will send less data to the client? See also https://kadira.io/academy/improve-cpu-and-network-usage/ for how to do this efficiently across lots of clients.

aashuagg commented 10 years ago

Thanks Andrew. using TimeSync.isSynced() did the trick. I modified my code like this:

getServerTime = function(){
    var serverTime;
    if(!TimeSync.isSynced()){
        TimeSync.resync();
    }else{
        serverTime = Deps.nonreactive(function(){
            return TimeSync.serverTime();
        })
    }
    return serverTime;
}

helper method:

    var serverTime = getServerTime();
    console.log("current event serverTime", serverTime);
    return Event.find({'startDate': {$gte: new Date(serverTime)}});

BTW I am filtering data at server side, but there is another subscription on Event collection in same template, so I have to filter data at client side once more.