0 day streak
go / intermediate
Snippet

Implementing Channel Timeouts with select and time.After

To prevent concurrent operations from blocking indefinitely, you can implement timeouts using a select statement paired with time.After. The time.After function returns a channel that sends the current time after a specified duration, serving as a trigger to exit or abort the blocking wait.

snippet.go
go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
package main
import (
"fmt"
"time"
)
func fetchData() <-chan string {
ch := make(chan string)
go func() {
time.Sleep(2 * time.Second) // Simulate slow work
ch <- "data source payload"
}()
return ch
}
func main() {
dataChan := fetchData()
select {
case result := <-dataChan:
fmt.Println("Received:", result)
case <-time.After(1 * time.Second):
fmt.Println("Operation timed out!")
}
}
Breakdown
1
select { ... }
Enables a goroutine to wait on multiple communication operations simultaneously, executing the first one that becomes ready.
2
case result := <-dataChan:
Succeeds and executes if data source finishes and sends data before the timeout completes.
3
case <-time.After(1 * time.Second):
Receives from the timeout channel after 1 second, aborting the wait if the main channel is still blocked.