Timeout reading from a channel with select
suggest changeReceiving 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.- we don't care about the value read from timeout channel. We only care that value was sent on the channel
- we use
select
to wait on 2 channels:chResult
and a timeout channel select
finishes when receive on one of the 2 channels completes- we either get the value on
chResult
before timeout expires or we receive the value from timeout channel
Found a mistake? Have a question or improvement idea?
Let me know.
Table Of Contents