-
Notifications
You must be signed in to change notification settings - Fork 1
/
connpool_example_test.go
145 lines (115 loc) · 3.15 KB
/
connpool_example_test.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
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
package goconnpool
import (
"bufio"
"context"
"flag"
"fmt"
net "net"
"net/http"
"time"
)
func ExampleNewConnPool_base() {
cfg := NewConfig(&flag.FlagSet{})
flag.Parse() // XXX: This call is required to fill config variables
// Create a pool
pool := NewConnPool(*cfg)
// Register some servers
pool.RegisterServer("127.0.0.1:1234")
pool.RegisterServer("8.8.8.8:1234")
for i := 0; i < 10; i++ {
cn, err := pool.OpenConnNonBlock(context.Background()) // Context could be cancelable here
if err != nil {
// All servers are down or ratelimited: try again later
time.Sleep(100 * time.Millisecond)
continue
}
if _, err := cn.Write([]byte("Hello")); err != nil {
// Can't write the message to the server.
// Force-close connection
cn.Close()
return
}
// This call moves a connection back to pool
cn.ReturnToPool()
}
}
func ExampleNewConnPool_httpRequest() {
cfg := NewConfig(&flag.FlagSet{})
flag.Parse() // XXX: This call is required to fill config variables
// Create a pool
pool := NewConnPool(*cfg)
// Register some servers
pool.RegisterServer("127.0.0.1:1234")
cn, _ := pool.OpenConn(context.Background()) // success connection
defer cn.Close()
// You could implement your own transport in the same way:
// https://golang.org/pkg/net/http/#RoundTripper
req, _ := http.NewRequest(http.MethodGet, "/some", nil)
req.Write(cn)
resp, _ := http.ReadResponse(bufio.NewReader(cn), req)
fmt.Println(resp.ContentLength)
}
func ExampleNewConnPool_blockingCalls() {
cfg := NewConfig(&flag.FlagSet{})
flag.Parse() // XXX: This call is required to fill config variables
// Create a pool
pool := NewConnPool(*cfg)
// Register some servers
pool.RegisterServer("127.0.0.1:1111")
pool.RegisterServer("127.0.0.1:2222")
// It is simplier to use WithTimeout() here ;)
ctx, cancel := context.WithCancel(context.Background())
go func() {
time.Sleep(10 * time.Second)
cancel() // timeout
}()
// Following call will blocks until any connection (to port 1111 or to port 2222) will be established.
// We will cancel the request if we still can't connect after 10 seconds
cn, err := pool.OpenConn(ctx)
if err != nil {
// Timeout
}
defer cn.Close()
// use your conn
}
type MyConn struct {
net.Conn
addr string
}
func (cn MyConn) Hello() string {
return fmt.Sprintf("Hello from %s", cn.addr)
}
type MyDialer struct{}
func (MyDialer) Dial(ctx context.Context, addr string) (net.Conn, error) {
return MyConn{addr: addr}, nil
}
// Example shows how to use custom dialer.
//
// type MyConn struct {
// net.Conn
//
// addr string
// }
//
// func (cn MyConn) Hello() string {
// return fmt.Sprintf("Hello from %s", cn.addr)
// }
//
// type MyDialer struct{}
//
// func (MyDialer) Dial(ctx context.Context, addr string) (net.Conn, error) {
// return MyConn{addr: addr}, nil
// }
//
func ExampleNewConnPool_dialer() {
p := NewConnPool(Config{
Dialer: MyDialer{},
})
p.RegisterServer("google.com")
cn, _ := p.OpenConn(context.Background())
origCn := cn.OriginalConn().(MyConn)
defer cn.ReturnToPool()
// Use origCn in some way
fmt.Println(origCn.Hello())
// Output: Hello from google.com
}