ruk·si

Go
Channels and Time

Updated at 2022-01-20 08:25

Go standard library time provides various useful helper channels.

Creating a channel that will send a message after the specified time.

package main

import (
    "time"
)

func assert(condition bool) {
    if !condition {
        panic("assert failed")
    }
}

func main() {
    fails := make(chan string)
    go func() {
        time.Sleep(600 * time.Millisecond)
        fails <- "success!"
    }()
    select {
    case <-fails:
        assert(false)
    case <-time.After(500 * time.Millisecond):
        assert(true)
    }

    completes := make(chan string)
    go func() {
        time.Sleep(400 * time.Millisecond)
        completes <- "success!"
    }()
    select {
    case <-completes:
        assert(true)
    case <-time.After(500 * time.Millisecond):
        assert(false)
    }
}

Goroutine timeout with time.After.

package main

import (
    "fmt"
    "time"
)

func worker(shutToStart chan bool) {
    <-shutToStart
    for {
        select {
        // use other `case` here to receive work
        case <-time.After(500 * time.Millisecond):
            fmt.Println("Timeout!")
            return
        }
    }
}

func main() {
    shutToStart := make(chan bool)
    for i := 0; i < 10; i++ {
        go worker(shutToStart)
    }
    close(shutToStart)
    time.Sleep(1 * time.Second)
    fmt.Print("End.")
}

Heartbeat pattern with time.Tick. Doing something in intervals.

package main

import (
    "fmt"
    "time"
)

func worker(shutToStart chan bool) {
    <-shutToStart
    for tick := range time.Tick(450 * time.Millisecond) {
        // you'd do the heartbeat operations here...
        // or use plain `for` followed by a `select` to do branching
        fmt.Println("Now!", tick)
    }
}

func main() {
    shutToStart := make(chan bool)
    for i := 0; i < 5; i++ {
        go worker(shutToStart)
    }
    close(shutToStart)
    time.Sleep(1 * time.Second)
    fmt.Print("End.")
}