DEV Community

Julian-Chu
Julian-Chu

Posted on

[Go] for-select with timer

#go

"for-select" is very important in golang for non-blocking operation. "Timer" is a good partner with for-select to handle timeout and performance issue.

In this post, I show some use cases, how for-select with timer work together.

Timeout

Listen to 2 channels, if no receive from any channel in 1s, it goes to the timeout case

 for { select { case a := <-ch1: fmt.Println(a) case b := <-ch2: fmt.Println(b) case <-time.After(time.Second): // timeout, do something } } 

Interval

Sometimes we can see new gophers write the following code:

 for { select { case a := <-ch1: fmt.Println(a) case b := <-ch2: fmt.Println(b) default: // always non-block here,  } // no interval, run this for-loop intensively } 

Then most of usage CPU maybe occupied because of intensive non-blocking infinite loop. We could use timeout case to avoid it, or add interval to entire for loop like this.

 for { select { case a := <-ch1: fmt.Println(a) case b := <-ch2: fmt.Println(b) default: } <-time.After(time.Second) // or time.sleep(time.Second) } 

The for loop now has 1s interval.

Timer

Sometimes we would like to set timer to break for-loop.
You may implement like following code:

 t := time.NewTimer(time.Second * 5) loop: for { select { case a := <-ch1: fmt.Println(a) case b := <-ch2: fmt.Println(b) case <-time.After(time.Millisecond *500): case <-t.C: break loop } } 

The code works, but there's a potential issue in this implementation. Be careful, "select" statement chooses any non-blocked case randomly, for example, even if the timer is fired, select can pick up another cases when they're non-blocked.
So we can improve it by adding another select statement.

 t := time.NewTimer(time.Second * 5) loop: for { select { case <-t.C: // if timer is fired, break the loop  break loop default: // timer is not fired, non-blocked  } select { case a := <-ch1: fmt.Println(a) case b := <-ch2: fmt.Println(b) case <-time.After(time.Millisecond *500): } } 

I think these are common use cases for for-select with Timer.
If any mistake and question, please feel free to write comments.

Top comments (0)