Client and server clocks out of sync even when using anvil.tz

What I’m trying to do:
I’m trying to precisely measure the time it takes to spin up a server instance, execute a server function and the travel time of the output back to the client.

What I’ve tried and what’s not working:
I’ve tried logging the time at each “milestone” by using the datetime module along with anvil.tz. According to the documentation, using datetime.now(anvil.tz.tzutc()) should stamp the datetime object with the timezone of the server. However, the clocks are still out of sync.

Code Sample:

Client

  def outlined_button_1_click(self, **event_args):
    print(f"Clicked button on client: {datetime.now(anvil.tz.tzutc()).time()}")
    test = anvil.server.call('return_a_number')
    print(f"Server output reached client: {datetime.now(anvil.tz.tzutc()).time()}")

Server

@anvil.server.callable
def return_a_number():
  print(f"Server instance created: {datetime.now(anvil.tz.tzutc()).time()}")
  pass # execute some code
  print(f"Server function finished executing: {datetime.now(anvil.tz.tzutc()).time()}")
  return 6

Results
image

As you can see, it shows that the server output reached the client before the server function finished executing. As this cannot be the case, the clocks are out of sync.

Clone link:
share a copy of your app

That’s normal. You can’t rely on two computers having the same time.

Nowadays we are spoiled, and a few seconds feels bad, but a few years back it was common to see minutes.

1 Like

It was my understanding that anvil.tz was meant to be a solution for this.

It makes it a bit difficult to measure the bootup time of the server instance when I do not know what the delta is between the client and server clocks.

Although I suppose I could do the server call a large number of times for an app with minimal imports on the server side and a single callable function (as the one posted above). Then I could consider the smallest difference between the button click log and the “server instance created” log as the the delta in the clocks.

anvil.tz is a module for dealing with timezones.
The documentation mentions that anvil.tz.tzutc() is the timezone of the server, which it is.
i.e. if you want your timezone on the client to match the one on Anvil’s server then use UTC as the timezone.
But this says nothing about the accuracy/synchronisation of the client’s clock time compared with the server’s clock time.

Worth double checking that you’re local computer has the correct clock time.
If you run an app in the IDE and in the client console do print(datetime.now()).
Then check it’s what you expect when compared with, say, time.is.
You can also do this in a server console to compare the client vs server time (though the server response will have some latency).
(When I do this I have times inline with what i’d expect to see)

But as Stefano mentions, Anvil can’t guarantee the system time of your users matches the system time on Anvil’s server.

1 Like

Related note: search the web for " Falsehoods programmers believe about time". We’ve all fallen for one (or more!) of these. Summary: Murphy was an optimist…