ruk·si

Go
Timers

Updated at 2014-02-02 07:18

Timers. Timers allow waiting that can be cancelled.

package main

import (
    "fmt"
    "time"
)

func main() {
    timer1 := time.NewTimer(time.Second * 2)
    <-timer1.C
    fmt.Println("Timer 1 expired")

    timer2 := time.NewTimer(time.Second)
    go func() {
        <-timer2.C
        fmt.Println("Timer 2 expired")
    }()
    wasStopped := timer2.Stop()
    if wasStopped {
        fmt.Println("Timer 2 stopped")
    }
}

Tickers. Tickers allow doing something at regular intervals.

package main

import (
    "fmt"
    "time"
)

func main() {
    ticker := time.NewTicker(time.Millisecond * 500)
    go func() {
        for t := range ticker.C {
            fmt.Println("Tick at", t)
        }
    }()
    time.Sleep(time.Second * 2)
    ticker.Stop()
    fmt.Println("Ticker stopped.")
}

Rate limiting. Process one request every 200ms.

package main

import (
    "fmt"
    "time"
)

func main() {
    requests := make(chan int, 10)
    for i := 1; i <= 10; i++ {
        requests <- i
    }
    close(requests)

    limiter := time.Tick(time.Millisecond * 200)
    for req := range requests {
        <-limiter
        fmt.Println("request", req, "processed at", time.Now())
    }
}

Rate limiting in bursts. Process one request every 200ms, but inactivity allows to process multiple requests in parallel. This processes 3 requests when it starts, then processes one request every 200ms.

package main

import (
    "fmt"
    "time"
)

func main() {
    requests := make(chan int, 10)
    for i := 1; i <= 10; i++ {
        requests <- i
    }
    close(requests)

    burstyLimiter := make(chan time.Time, 3)
    for i := 0; i < 3; i++ {
        burstyLimiter <- time.Now()
    }
    go func() {
        for t := range time.Tick(time.Millisecond * 200) {
            burstyLimiter <- t
        }
    }()

    for req := range requests {
        <-burstyLimiter
        fmt.Println("request", req, "processed at", time.Now())
    }
}

Sources