forked from pangudashu/memcache
-
Notifications
You must be signed in to change notification settings - Fork 0
/
pool.go
105 lines (88 loc) · 1.67 KB
/
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
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
package memcache
import (
"sync"
"time"
)
//连接池
type ConnectionPool struct {
pool chan *Connection
address string
maxCnt int
totalCnt int
idleTime time.Duration
sync.Mutex
}
func open(address string, maxCnt int, initCnt int, idelTime time.Duration) (pool *ConnectionPool) {
pool = &ConnectionPool{
pool: make(chan *Connection, maxCnt),
address: address,
maxCnt: maxCnt,
idleTime: idelTime,
}
for i := 0; i < initCnt; i++ {
conn, err := connect(address)
if err != nil {
continue
}
pool.totalCnt++
pool.pool <- conn
}
return pool
}
func (this *ConnectionPool) Get() (conn *Connection, err error) {
for {
conn, err = this.get()
if err != nil {
return nil, err
}
if conn.lastActiveTime.Add(this.idleTime).UnixNano() > time.Now().UnixNano() {
break
} else {
this.Release(conn)
}
}
conn.lastActiveTime = time.Now()
return conn, err
}
func (this *ConnectionPool) get() (conn *Connection, err error) {
select {
case conn = <-this.pool:
return conn, nil
default:
}
this.Lock()
if this.totalCnt >= this.maxCnt {
//阻塞,直到有可用连接
conn = <-this.pool
this.Unlock()
return conn, nil
}
//create new connect
conn, err = connect(this.address)
if err != nil {
this.Unlock()
return nil, err
}
this.totalCnt++
this.Unlock()
return conn, nil
}
func (this *ConnectionPool) Put(conn *Connection) {
if conn == nil {
return
}
this.pool <- conn
}
func (this *ConnectionPool) Release(conn *Connection) {
conn.Close()
this.Lock()
this.totalCnt--
this.Unlock()
}
//clear pool
func (this *ConnectionPool) Close() {
for i := 0; i < len(this.pool); i++ {
conn := <-this.pool
conn.Close()
}
}