1
\$\begingroup\$

I want to allow a user to redeem a token every X time (i.e. 24 hours). Once they redeem it, they must wait X time again before redeeming the next item. This ensures that users must visit the app daily to continue gaining tokens.

I'm not sure how to work with clock differences between machines. What if

Server B:      9:03:41
User A tablet: 9:03.59
Server C:      9:05:23

(assume they all have the same date and all are AM)

User A's tablet makes a request and server B response with "Token available". The user then tries to immediately redeem the token, but server C responses with "Sorry, token not yet available." This would obviously be annoying to the user.

I could potentially handle this on the server. If the server says a token is available, then set a flag that actually guarantees that it is available.

But what if I want to actually let the user know how much time is left before they receive their next token. If all the servers have a different clock time, then all requests for time left would return a slightly different time.

I don't think I could rely on client time, since the user may play with different devices.

How could I handle this?

\$\endgroup\$
1
  • \$\begingroup\$ That's why you should sync your server times to a good accuracy (possible with NTP) \$\endgroup\$ Aug 3, 2015 at 11:36

2 Answers 2

0
\$\begingroup\$

Time is a fleeting concept, relative to different observers and mostly illusive. It is up to you to decide how to deal with it.

My advice is that you should synchronize time between your servers. The easiest way is to use an authoritative time server. This ensures that all your machines agree, up to a useful error margin, with some source such as an NTP server.

You should synchronize client time using server as a time source. Do not trust any timestamp or other data from the client. In order to implement clock synchronization, you can borrow a fairly simple existing protocol such as SNTP. There is a detailed explanation in another SE answer.

UTC time should be used everywhere, it is much simpler that way.

Now for your example

You describe a situation where a single client session is divided between several servers, and each of these servers can 'chime in' to handle any request. This means you have at least two options:

  1. Update client time to match the current server each time your client changes servers.
  2. Update client time to match the authoritative time server, and ignore small discrepancies.

I would prefer the 2nd option.

You will also need to store current state of said session globally, somewhere where every server can read it. Lets say you decided to use stand-alone database as a state storage.

For your example, this means when client presses a button and requests a token redeem, write something in the database, like "client with login id 'dan_f' succesfully redeemed token 'santa hat' at 2015-08-03T13:45:30 (authoritative server UTC time)" and set client button text to your token cooldown.

You can periodically sync button text, but it is not really necessary, time discrepancy should be too small to care anyway. If client disconnects and reconnects, sync time as usual and update client button text using timestamp from previously written DB record. If user presses button and requests another redeem, use DB record again to check if redeeming is available, and sync button text in process. Again, with all servers synced with one master, and client synced with that master as well, time difference should be too small to care.

\$\endgroup\$
0
\$\begingroup\$

Make the client request the time remaining from the server that handles giving out the token. Then count down from that using the local clock.

Also I believe that you could synchronize your servers much better than that and this wouldn't be a problem as long as your app can handle the disagreeing servers.

And also probably you shouldn't let a user push a button to get a token until he can actually get it, so just request that from the server too.

\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .