-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmain.go
63 lines (60 loc) · 1.56 KB
/
main.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
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
package main
import (
"context"
"fmt"
"time"
)
// main demonstrates how to utilise the select timeout
// pattern. Frequently done with a context in order
// to time-box a particular goroutine and have it
// terminate if it is running for too long.
//
// If contexts are new to you, just know a context can be
// used to time something out with time, or explicitly by
// calling the cancellation functions.
// They can also be used to share data across boundaries by
// storing data within them, but that is not something of use here.
//
// We give a goroutine upto 2 seconds to get through all the generated
// values. Should it be too slow, we terminate it.
func main() {
c := generator()
ctx, cancelFn := context.WithDeadline(context.Background(), time.Now().Add(2*time.Second))
defer cancelFn()
/*
Here we will demonstrate how a long running goroutine
can be caused to terminate. The done channel here is
used to solely not exit immediately and give the goroutine
some time to run.
*/
done := make(chan struct{})
go func() {
defer close(done)
for {
select {
case i, ok := <-c:
if !ok {
fmt.Println("we generated all the values")
return
}
fmt.Println("received value: ", i)
case <-ctx.Done():
fmt.Println("timed out, error:", ctx.Err())
return
}
}
}()
<-done
}
// generator yields the integer values 1 through 5.
func generator() <-chan int {
out := make(chan int)
go func() {
for i := range 5 {
out <- i
time.Sleep(500 * time.Millisecond) // Exceed the context deadline
}
close(out)
}()
return out
}