Golang Monotonic Time: proposal reasons

Golang Monotonic Time: proposal reasons

denniselite

One of most the important proposals in last Go 1.9 release was the “Monotonic Elapsed Time Measurements in Go”. It solved the main problem of time-related operations when operation system affected the clock tickers. 

Common proposal info: https://github.com/golang/proposal/blob/master/design/12914-monotonic.md

Theory

Our сlocks can't work durably without errors. Sometimes you can see when your analog clocks have a couple of minutes delays between more reliable clocks and you can reset it to match the reference. It is a normal practice for us but unfortunately computers have similar problems.

The algorithms of system clock compare and fix local time by higher-accuracy reference clock which located in an available network. If the local clock is observed then it can be slowed a little and if it slightly behind then sped up by counting some ticks twice. Also, for highest accuracy computer may add new algorithms and features to tick generations rules, so, in normal situations, system clocks works perfectly. 

But the problem arises if computer clocks are turned off and after launch, the system will have a wrong time before synchronization. And another reason that time tickers may ignore leaps for time fixing and do it in unpredictable moments. 

Practice

The problems of system clock starts when we are catching some system time leaps in the Go runtime, as example:

t1 := time.Now()
// 10 ms of work
t2 := time.Now()
// 10 ms of work
t3 := time.Now()
// 10 ms of work
const f = "15:04:05.000"
fmt.Println(t1.Format(f), t2.Sub(t1), t2.Format(f), t3.Sub(t2), t3.Format(f))

And the Go 1.8 will return 

23:59:59.985 10ms 23:59:59.995 -990ms 23:59:59.005

-990ms? Yes - we got the negative value. Negative value in that case occurred because after 23:59:59.995 point system had delayed next second for synchronization with the higher-accuracy reference clock. 

Another case, now we have the timezone changing time in period 1:00 AM - 2:00 AM and we lost time accuracy again because In Go 1.8, the result will: 

t1 := time.Now()
// 10 ms of work
t2 := time.Now()
// 10 ms of work
t3 := time.Now()
// 10 ms of work
const f = "15:04"
fmt.Println(t1.Format(f), t2.Sub(t1), t2.Format(f), t3.Sub(t2), t3.Format(f))

and return:

00:59 10ms 00:59 10ms 02:00

So you can see that we’ve got a difference in runtime with 61-minute duration but the convenient variant should be

00:59 10ms 00:59 10ms 01:00

Because in runtime we have the only 10ms difference between t2 and t3 difference.

Report Page