Channels and select:
*Timeout reading from a channel with select
Receiving from a channel with <- chan or for range loop blocks.
Sometimes you want to limit time waiting for a value on a channel.
It’s possible with select:
func main() {
chResult := make(chan int, 1)
go func() {
time.Sleep(1 * time.Second)
chResult <- 5
fmt.Printf("Worker finished")
}()
select {
case res := <-chResult:
fmt.Printf("Got %d from worker\n", res)
case <-time.After(100 * time.Millisecond):
fmt.Printf("Timed out before worker finished\n")
}
}
Timed out before worker finished
Let's dig into how this works:
select {
case res := <-chResult:
fmt.Printf("Got %d from worker\n", res)
case <-time.After(100 * time.Millisecond):
fmt.Printf("Timed out before worker finished\n")
}
time.After returns a channel on which a value will be enqueued after a given time (100 milliseconds in our example). It's worth nothing that it's at least 100 ms and can be more. Let's call it a timeout channel.
select to wait on 2 channels: chResult and a timeout channel
select finishes when receive on one of the 2 channels completes
chResult before timeout expires or we receive the value from timeout channel