-
Notifications
You must be signed in to change notification settings - Fork 87
/
Copy pathproxy_conn_pool.go
72 lines (64 loc) · 1.66 KB
/
proxy_conn_pool.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
package main
import (
"log"
"sync"
)
type Pooler interface {
Create(pool *ConnHandlerPool) (*ConnHandler, error)
Remove(conn *ConnHandler)
IsActive(conn *ConnHandler) bool
}
type ConnHandlerPool struct {
Size int
Pooler Pooler
mu sync.Mutex
conns []*ConnHandler
}
func (connPool *ConnHandlerPool) Init() {
connPool.conns = make([]*ConnHandler, 0, connPool.Size)
log.Printf("init connection pool, len %d, cap %d", len(connPool.conns), cap(connPool.conns))
}
func (connPool *ConnHandlerPool) Get() (*ConnHandler, error) {
for {
if len(connPool.conns) == 0 {
conn, err := connPool.Pooler.Create(connPool)
log.Println("create connection: ", conn, err)
if err != nil {
return nil, err
}
return conn, nil
} else {
conn, err := connPool.getConn()
if conn != nil {
return conn, err
}
}
}
}
func (connPool *ConnHandlerPool) getConn() (*ConnHandler, error) {
connPool.mu.Lock()
defer connPool.mu.Unlock()
if len(connPool.conns) == 0 {
return nil, nil
}
conn := connPool.conns[len(connPool.conns)-1]
connPool.conns = connPool.conns[:len(connPool.conns)-1]
if connPool.Pooler.IsActive(conn) {
log.Println("get connection from pool: ", conn)
return conn, nil
} else {
return nil, nil
}
}
func (connPool *ConnHandlerPool) Return(conn *ConnHandler) {
connPool.mu.Lock()
defer connPool.mu.Unlock()
if len(connPool.conns) >= connPool.Size {
log.Println("pool is full, remove connection: ", conn)
connPool.Pooler.Remove(conn)
} else {
connPool.conns = connPool.conns[:len(connPool.conns)+1]
connPool.conns[len(connPool.conns)-1] = conn
log.Println("return connection:", conn, ", poolsize is ", len(connPool.conns))
}
}