-
Notifications
You must be signed in to change notification settings - Fork 153
/
09_context.go
120 lines (103 loc) · 2.66 KB
/
09_context.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
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
package main
import (
"fmt"
"time"
"golang.org/x/net/context"
)
type key int
const appStartTSKey key = 0
const userIPKey key = 1
const userAgentKey key = 2
func setContextWithAppStartTS(ctx context.Context, ts string) context.Context {
return context.WithValue(ctx, appStartTSKey, ts)
}
func setContextWithIP(ctx context.Context, userIP string) context.Context {
return context.WithValue(ctx, userIPKey, userIP)
}
func setContextWithUserAgent(ctx context.Context, userAgent string) context.Context {
return context.WithValue(ctx, userAgentKey, userAgent)
}
func getAppStartTSFromContext(ctx context.Context) (string, bool) {
ts, ok := ctx.Value(appStartTSKey).(string)
return ts, ok
}
func getIPFromContext(ctx context.Context) (string, bool) {
userIP, ok := ctx.Value(userIPKey).(string)
return userIP, ok
}
func getUserAgentFromContext(ctx context.Context) (string, bool) {
userAgent, ok := ctx.Value(userAgentKey).(string)
return userAgent, ok
}
func main() {
func() {
ctx := context.Background()
ctx = setContextWithAppStartTS(ctx, time.Now().String())
ctx = setContextWithIP(ctx, "1.2.3.4")
ctx = setContextWithUserAgent(ctx, "Linux")
fmt.Println(ctx)
fmt.Println(getAppStartTSFromContext(ctx))
fmt.Println(getIPFromContext(ctx))
fmt.Println(getUserAgentFromContext(ctx))
fmt.Println("Done 1:", ctx)
}()
/*
Done 1: context.Background.WithValue(0, "2015-09-02 22:38:00.640981471 -0700 PDT").WithValue(1, "1.2.3.4").WithValue(2, "Linux")
*/
fmt.Println()
func() {
timeout := 100 * time.Millisecond
processingTime := time.Nanosecond
ctx, cancel := context.WithTimeout(context.Background(), timeout)
cancel()
send(ctx, processingTime)
fmt.Println("Done 2")
}()
/*
send Timeout: context canceled
Done 2
*/
fmt.Println()
func() {
timeout := 100 * time.Millisecond
processingTime := time.Nanosecond
ctx, cancel := context.WithTimeout(context.Background(), timeout)
defer cancel()
send(ctx, processingTime)
fmt.Println("Done 3")
}()
/*
send Done!
Done 3
*/
fmt.Println()
func() {
timeout := 100 * time.Millisecond
processingTime := time.Minute
ctx, cancel := context.WithTimeout(context.Background(), timeout)
defer cancel()
send(ctx, processingTime)
fmt.Println("Done 4")
}()
/*
send Timeout: context deadline exceeded
Done 4
*/
}
func send(ctx context.Context, processingTime time.Duration) {
done := make(chan struct{})
go func() {
time.Sleep(processingTime)
done <- struct{}{}
}()
select {
case <-done:
fmt.Println("send Done!")
return
case <-ctx.Done():
// Done channel is closed when the deadline expires(times out)
// or canceled.
fmt.Println("send Timeout:", ctx.Err())
return
}
}