publish timeouts
This commit is contained in:
parent
7cd0fc89af
commit
7aab87b272
@ -32,7 +32,7 @@ Channels
|
|||||||
# Channel Directions
|
# Channel Directions
|
||||||
# Synchronization
|
# Synchronization
|
||||||
Select
|
Select
|
||||||
# Timeouts
|
Timeouts
|
||||||
# Scatter Gather
|
# Scatter Gather
|
||||||
# Rate Limiting
|
# Rate Limiting
|
||||||
# Worker Pools
|
# 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
|
package main
|
||||||
|
|
||||||
import "time"
|
import "time"
|
||||||
import "fmt"
|
import "fmt"
|
||||||
|
|
||||||
func main() {
|
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() {
|
go func() {
|
||||||
time.Sleep(time.Millisecond * 1500)
|
time.Sleep(time.Second * 2)
|
||||||
c <- "ready"
|
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() {
|
go func() {
|
||||||
select {
|
time.Sleep(time.Second * 2)
|
||||||
case msg := <-c:
|
c2 <- "result 2"
|
||||||
fmt.Println(msg)
|
|
||||||
case <-time.After(time.Millisecond * 1000):
|
|
||||||
fmt.Println("timeout")
|
|
||||||
}
|
|
||||||
d <- true
|
|
||||||
}()
|
}()
|
||||||
<-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