publish timeouts
This commit is contained in:
parent
7cd0fc89af
commit
7aab87b272
@ -32,7 +32,7 @@ Channels
|
||||
# Channel Directions
|
||||
# Synchronization
|
||||
Select
|
||||
# Timeouts
|
||||
Timeouts
|
||||
# Scatter Gather
|
||||
# Rate Limiting
|
||||
# Worker Pools
|
||||
|
@ -1,25 +1,50 @@
|
||||
// _Timeouts_ are important for programs that connect to
|
||||
// external resources or that otherwise need to bound
|
||||
// execution time. Implementing timeouts in Go is easy and
|
||||
// elegant thanks to channels and `select`.
|
||||
|
||||
package main
|
||||
|
||||
import "time"
|
||||
import "fmt"
|
||||
|
||||
func main() {
|
||||
c := make(chan string)
|
||||
d := make(chan bool, 1)
|
||||
|
||||
// For our example, suppose we're execting an external
|
||||
// call that returns its result on a channel `c1`
|
||||
// after 2s.
|
||||
c1 := make(chan string)
|
||||
go func() {
|
||||
time.Sleep(time.Millisecond * 1500)
|
||||
c <- "ready"
|
||||
time.Sleep(time.Second * 2)
|
||||
c1 <- "result 1"
|
||||
}()
|
||||
|
||||
// Here's the `select` implementing a timeout.
|
||||
// `res := <-c1` awaits the result and `<-Time.After`
|
||||
// awaits a value to be sent after the timeout of
|
||||
// 1s. Since `select` proceeds with the first
|
||||
// receive that's ready, we'll take the timeout case
|
||||
// if the operation takes more than the allowed 1000ms.
|
||||
select {
|
||||
case res := <-c1:
|
||||
fmt.Println(res)
|
||||
case <-time.After(time.Second * 1):
|
||||
fmt.Println("timeout 1")
|
||||
}
|
||||
|
||||
// If we allow a longer timeout of 3s, then the receive
|
||||
// from `c2` will succeed and we'll print the result.
|
||||
c2 := make(chan string)
|
||||
go func() {
|
||||
select {
|
||||
case msg := <-c:
|
||||
fmt.Println(msg)
|
||||
case <-time.After(time.Millisecond * 1000):
|
||||
fmt.Println("timeout")
|
||||
}
|
||||
d <- true
|
||||
time.Sleep(time.Second * 2)
|
||||
c2 <- "result 2"
|
||||
}()
|
||||
<-d
|
||||
select {
|
||||
case res := <-c2:
|
||||
fmt.Println(res)
|
||||
case <-time.After(time.Second * 3):
|
||||
fmt.Println("timeout 2")
|
||||
}
|
||||
}
|
||||
|
||||
// todo: cancellation?
|
||||
|
11
examples/timeouts/timeouts.sh
Normal file
11
examples/timeouts/timeouts.sh
Normal file
@ -0,0 +1,11 @@
|
||||
# Running this program shows the first operation timing
|
||||
# out and the second succeeding.
|
||||
$ go run timeouts.go
|
||||
timeout 1
|
||||
result 2
|
||||
|
||||
# Using this `select` timeout pattern requires
|
||||
# communicating results over channels. This is a good
|
||||
# idea in general because other important Go features are
|
||||
# based on channels and `select`. We'll look at two
|
||||
# examples of this next: timers and tickers.
|
Loading…
x
Reference in New Issue
Block a user