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