My assumption is that time always runs forward, but apparently sometimes it doesn’t happen this way.
I have the following example:
var LOOP_MS = 100;
var prevCall = +new Date();
setTimeout(function loop() {
foobar();
setTimeout(loop, LOOP_MS);
}, LOOP_MS);
function foobar() {
var now = +new Date(),
diff = now - prevCall; // expected to be somewhere around LOOP_MS
// do stuff
console.log(diff);
prevCall = now;
}
Now, most of the time it works as expected, and diff
shows a number close to 100. Of course, in the real-life scenario I’d expect the number to go up, especially when the user’s computer is performing some heavy operation.
What I don’t expect, is to see a negative number, and yet it happens. How is possible? Am I missing something? I thought maybe it could be caused by a different timezone, but it’s not. I also see it in different browsers (Chrome, Firefox, Safari), and the diff values are quite inconsistent: anything from -9, to -100 000.
It happens in about 0.025% of cases on production, so it’s not a big issue, but I’m wondering how on earth can it possibly happen (even in theory)?
I think I managed to reproduce it a couple of times locally by running the script in a slow VM and emulating high CPU load, but I still don’t see why the function would show a negative number (meaning, now
is older than prevCall
).
Most computers are configured to use NTP servers to set the system clock.
As the system clock is set the first time normally it will stay in sync without need of updates.
At times (rarely) for various reasons the system clock may go out of sync.
As the system clock doesn't match with the NTP server time it is updated and may go backwards.
NTP services are (normally) configured to avoid the clock going backwards: if the "gap" is small enought the NTP daemon tries instead to "slow down" the system clock until it's again in sysnc. But as just said this depends on the configuration and the size of the time gap.
I think all the above cause in rare cases the issue you're seeing.
You may find this interesting: Is there a way to ensure ntp synced clock never moves backwards?
If you're on macOS you may try opening the console and searching for ntpd
.
On my machine (a MBP with 10.9.5) I see a couple of lines like this...
Apr 2 01:11:40 mac-di-paolo.local ntpd[46]: ntpd: wake time set -1.848017 s
...that logs a system clock adjustment.
prevCall
is a global variable with a generic name - is it possible that some other function writes to it?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With