@@ -2,9 +2,8 @@ package rethinkdb
2
2
3
3
import (
4
4
"errors"
5
- "fmt"
6
- "net"
7
5
"sync"
6
+ "sync/atomic"
8
7
9
8
"golang.org/x/net/context"
10
9
"gopkg.in/fatih/pool.v2"
@@ -19,7 +18,8 @@ type Pool struct {
19
18
host Host
20
19
opts * ConnectOpts
21
20
22
- pool pool.Pool
21
+ conns []* Connection
22
+ pointer int32
23
23
24
24
mu sync.RWMutex // protects following fields
25
25
closed bool
@@ -36,36 +36,31 @@ func NewPool(host Host, opts *ConnectOpts) (*Pool, error) {
36
36
37
37
maxOpen := opts .MaxOpen
38
38
if maxOpen <= 0 {
39
- maxOpen = 2
39
+ maxOpen = 1
40
40
}
41
41
42
- p , err := pool .NewChannelPool (initialCap , maxOpen , func () (net.Conn , error ) {
43
- conn , err := NewConnection (host .String (), opts )
42
+ conns := make ([]* Connection , maxOpen )
43
+ var err error
44
+ for i := range conns {
45
+ conns [i ], err = NewConnection (host .String (), opts )
44
46
if err != nil {
45
47
return nil , err
46
48
}
47
-
48
- return conn , err
49
- })
50
- if err != nil {
51
- return nil , err
52
49
}
53
50
54
51
return & Pool {
55
- pool : p ,
56
- host : host ,
57
- opts : opts ,
52
+ conns : conns ,
53
+ pointer : - 1 ,
54
+ host : host ,
55
+ opts : opts ,
58
56
}, nil
59
57
}
60
58
61
59
// Ping verifies a connection to the database is still alive,
62
60
// establishing a connection if necessary.
63
61
func (p * Pool ) Ping () error {
64
- _ , pc , err := p .conn ()
65
- if err != nil {
66
- return err
67
- }
68
- return pc .Close ()
62
+ _ , _ , err := p .conn ()
63
+ return err
69
64
}
70
65
71
66
// Close closes the database, releasing any open resources.
@@ -79,37 +74,32 @@ func (p *Pool) Close() error {
79
74
return nil
80
75
}
81
76
82
- p .pool .Close ()
77
+ for _ , c := range p .conns {
78
+ err := c .Close ()
79
+ if err != nil {
80
+ return err
81
+ }
82
+ }
83
83
84
84
return nil
85
85
}
86
86
87
87
func (p * Pool ) conn () (* Connection , * pool.PoolConn , error ) {
88
88
p .mu .RLock ()
89
- defer p .mu .RUnlock ()
90
89
91
90
if p .closed {
91
+ p .mu .RUnlock ()
92
92
return nil , nil , errPoolClosed
93
93
}
94
+ p .mu .RUnlock ()
94
95
95
- nc , err := p .pool .Get ()
96
- if err != nil {
97
- return nil , nil , err
98
- }
99
-
100
- pc , ok := nc .(* pool.PoolConn )
101
- if ! ok {
102
- // This should never happen!
103
- return nil , nil , fmt .Errorf ("Invalid connection in pool" )
104
- }
105
-
106
- conn , ok := pc .Conn .(* Connection )
107
- if ! ok {
108
- // This should never happen!
109
- return nil , nil , fmt .Errorf ("Invalid connection in pool" )
96
+ pos := atomic .AddInt32 (& p .pointer , 1 )
97
+ if pos == int32 (len (p .conns )) {
98
+ atomic .StoreInt32 (& p .pointer , 0 )
110
99
}
100
+ pos = pos % int32 (len (p .conns ))
111
101
112
- return conn , pc , nil
102
+ return p . conns [ pos ], nil , nil
113
103
}
114
104
115
105
// SetInitialPoolCap sets the initial capacity of the connection pool.
@@ -138,67 +128,35 @@ func (p *Pool) SetMaxOpenConns(n int) {
138
128
139
129
// Exec executes a query without waiting for any response.
140
130
func (p * Pool ) Exec (ctx context.Context , q Query ) error {
141
- c , pc , err := p .conn ()
131
+ c , _ , err := p .conn ()
142
132
if err != nil {
143
133
return err
144
134
}
145
- defer pc .Close ()
146
135
147
136
_ , _ , err = c .Query (ctx , q )
148
-
149
- if c .isBad () {
150
- pc .MarkUnusable ()
151
- }
152
-
153
137
return err
154
138
}
155
139
156
140
// Query executes a query and waits for the response
157
141
func (p * Pool ) Query (ctx context.Context , q Query ) (* Cursor , error ) {
158
- c , pc , err := p .conn ()
142
+ c , _ , err := p .conn ()
159
143
if err != nil {
160
144
return nil , err
161
145
}
162
146
163
147
_ , cursor , err := c .Query (ctx , q )
164
-
165
- if err == nil {
166
- cursor .releaseConn = releaseConn (c , pc )
167
- } else {
168
- if c .isBad () {
169
- pc .MarkUnusable ()
170
- }
171
- pc .Close ()
172
- }
173
-
174
148
return cursor , err
175
149
}
176
150
177
151
// Server returns the server name and server UUID being used by a connection.
178
152
func (p * Pool ) Server () (ServerResponse , error ) {
179
153
var response ServerResponse
180
154
181
- c , pc , err := p .conn ()
155
+ c , _ , err := p .conn ()
182
156
if err != nil {
183
157
return response , err
184
158
}
185
- defer pc .Close ()
186
159
187
160
response , err = c .Server ()
188
-
189
- if c .isBad () {
190
- pc .MarkUnusable ()
191
- }
192
-
193
161
return response , err
194
162
}
195
-
196
- func releaseConn (c * Connection , pc * pool.PoolConn ) func () error {
197
- return func () error {
198
- if c .isBad () {
199
- pc .MarkUnusable ()
200
- }
201
-
202
- return pc .Close ()
203
- }
204
- }
0 commit comments