Go time

Monotonic clocks in go land

Golang Paris Go 1.8 Release Party

16 February 2017

Anisse Astier

Independent Embedded Linux kernel engineer

Time travel

Different times

Different times

Different times

Time jumps

Time warp

Leap smear: developers.google.com/time/smear

Go time

Go time

time.Now()

Returns wall clock

package main

import (
	"fmt"
	"time"
)

func main() {
    fmt.Println("Go time", time.Now())
}

Elapsed time

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))
}

Elapsed time

    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

Behind the times

C/C++

man 2 clock_gettime
CLOCK_REALTIME/CLOCK_MONOTONIC

Java

System.nanoTime

Python

time.monotnic

Once upon a time

Internal function:

runtime.nanotime

All in good time

All in good time

A fix has been merged for Go 1.9

It changes the internal representation of time.Time

All in good 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".

All in good time

    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+!

The test of time

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

Thank you

Golang Paris Go 1.8 Release Party

16 February 2017

Anisse Astier

Independent Embedded Linux kernel engineer