Go time
Monotonic clocks in go land
Golang Paris Go 1.8 Release Party
16 February 2017
Anisse Astier
Independent Embedded Linux kernel engineer
Golang Paris Go 1.8 Release Party
16 February 2017
Anisse Astier
Independent Embedded Linux kernel engineer
Leap smear: developers.google.com/time/smear
time.Now()
Returns wall clock
package main
import (
"fmt"
"time"
)
func main() {
fmt.Println("Go time", time.Now())
}
Go time 2017-02-19 10:44:01.408473506 +0100 CET Program exited.
package main
import (
"fmt"
"time"
)
func doSomething() {
time.Sleep(10 * time.Millisecond) //OMIT
}
func example2() { //OMIT
t1 := time.Now()
doSomething()
// Time jumps backwards (e.g after leap second adjustment)
//...
t2 := time.Now()
fmt.Println("Elapsed", t2.Sub(t1))
}
func timeNow() { //OMIT
fmt.Println("Go time", time.Now())
}
func main() {
t1 := time.Now() doSomething() //... t2 := time.Now() fmt.Println("Elapsed", t2.Sub(t1))
}
t1 := time.Now() doSomething() // Time jumps backwards (e.g after leap second adjustment) //... t2 := time.Now() fmt.Println("Elapsed", t2.Sub(t1))
--> this is bad code!
Result:
Elapsed -989.12989ms
C/C++
man 2 clock_gettime CLOCK_REALTIME/CLOCK_MONOTONIC
Java
System.nanoTime
Python
time.monotnic
Internal function:
runtime.nanotime
A fix has been merged for Go 1.9
It changes the internal representation of time.Time
The fix does not add new API functions.
But it does change the behaviour of:
time.Since(t) time.Until(t) // New in Go 1.8 ! t.Sub(u) t.Before(u)
Which are now "correct".
t1 := time.Now() doSomething() // Time jumps backwards (e.g after leap second adjustment) //... t2 := time.Now() fmt.Println("Elapsed", t2.Sub(t1))
--> this is now good code in Go 1.9+!
Slides for this talk: anisse.github.io/gotime
References:
- Cloudflare leap second blog post
- Go bug
- Design document of the fix: this is the primary source for this talk
Golang Paris Go 1.8 Release Party
16 February 2017
Anisse Astier
Independent Embedded Linux kernel engineer