Timeouts
Timeouts are important for programs that connect to external resources or that otherwise need to bound execution time. Implementing timeouts in Go is clean and simple using select and time.After.
Key Points
- Timeouts are essential for programs that interact with external resources.
selectwith atime.Afterchannel is the idiomatic way to implement timeouts in Go.time.Afterwaits for the duration to elapse and then sends the current time on the returned channel.- A timeout occurs if the
time.Aftercase is selected before the main operation's channel receives a value. - This pattern prevents goroutines from blocking indefinitely.
Timeout Example
This example shows how to use select with time.After to implement a timeout on a channel operation.
package main
import (
"fmt"
"time"
)
func main() {
c1 := make(chan string, 1)
go func() {
time.Sleep(2 * time.Second)
c1 <- "result 1"
}()
select {
case res := <-c1:
fmt.Println(res)
case <-time.After(1 * time.Second):
fmt.Println("timeout 1")
}
c2 := make(chan string, 1)
go func() {
time.Sleep(2 * time.Second)
c2 <- "result 2"
}()
select {
case res := <-c2:
fmt.Println(res)
case <-time.After(3 * time.Second):
fmt.Println("timeout 2")
}
}timeout 1
result 2Timeout Pattern
| Component | Role | Example |
|---|---|---|
| Operation Channel | The channel for the primary operation. | c1 := make(chan string, 1) |
time.After | Creates a channel that fires after a duration. | <-time.After(1 * time.Second) |
select | Waits on both channels. | select { case res := <-c1: ... case <-time.After(...): ... } |