benSooraj
benSooraj

Reputation: 465

time.NewTimer doesn't work as I expect

I have a fairly simple program, which is supposed to self-terminate after a specified duration of time (for example, one second)

The code:

package main

import (
    "fmt"
    "time"
)

func emit(wordChannel chan string, done chan bool) {
    defer close(wordChannel)

    words := []string{"The", "quick", "brown", "fox"}
    i := 0
    t := time.NewTimer(1 * time.Second)

    for {
        select {
        case wordChannel <- words[i]:
            i++
            if i == len(words) {
                i = 0
            }
        // Please ignore the following case
        case <-done:
            done <- true
            // fmt.Printf("Got done!\n")
            close(done)
            return
        case <-t.C:
            fmt.Printf("\n\nGot done!\n\n")
            return
        }
    }
}

func main() {

    mainWordChannel := make(chan string)
    // Please ignore mainDoneChannel
    mainDoneChannel := make(chan bool)

    go emit(mainWordChannel, mainDoneChannel)

    for word := range mainWordChannel {
        fmt.Printf("%s  ", word)
    }

}

I compile and execute the binary, and you can see the execution here.

That is clearly above 1 second.

Go's documentation on NewTimer reads this:

func NewTimer

func NewTimer(d Duration) *Timer

NewTimer creates a new Timer that will send the current time on its channel after at least duration d.

Can someone kindly help me understand what's happening here? Why isn't the program terminating exactly (or closely at least) after 1 second?

Upvotes: 2

Views: 658

Answers (1)

Vlad
Vlad

Reputation: 94

Timer works as intended. It sends a value to a channel. I think it is useful to read about select statement Each iteration in your loop can write to a channel. If > 1 communication can proceed there is no guarantee which are. So, if add delay to read loop like this :

for word := range mainWordChannel {
    fmt.Printf("%s  ", word)
    time.Sleep(time.Millisecond)
}

In this case, only read from timer.C can proceed. And program will end.

Upvotes: 4

Related Questions