@@ -124,29 +124,31 @@ var errServerClosed = errors.New("server was closed")
124
124
// use in this server is greater than the provided limit, errPoolLimit is
125
125
// returned.
126
126
func (server * mongoServer ) AcquireSocket (poolLimit int , timeout time.Duration ) (socket * mongoSocket , abended bool , err error ) {
127
- return server .acquireSocketInternal (poolLimit , timeout , false , 0 * time .Millisecond )
127
+ info := & DialInfo {
128
+ PoolLimit : poolLimit ,
129
+ ReadTimeout : timeout ,
130
+ WriteTimeout : timeout ,
131
+ Timeout : timeout ,
132
+ }
133
+ return server .acquireSocketInternal (info , false )
128
134
}
129
135
130
136
// AcquireSocketWithBlocking wraps AcquireSocket, but if a socket is not available, it will _not_
131
137
// return errPoolLimit. Instead, it will block waiting for a socket to become available. If poolTimeout
132
138
// should elapse before a socket is available, it will return errPoolTimeout.
133
- func (server * mongoServer ) AcquireSocketWithBlocking (
134
- poolLimit int , socketTimeout time.Duration , poolTimeout time.Duration ,
135
- ) (socket * mongoSocket , abended bool , err error ) {
136
- return server .acquireSocketInternal (poolLimit , socketTimeout , true , poolTimeout )
139
+ func (server * mongoServer ) AcquireSocketWithBlocking (info * DialInfo ) (socket * mongoSocket , abended bool , err error ) {
140
+ return server .acquireSocketInternal (info , true )
137
141
}
138
142
139
- func (server * mongoServer ) acquireSocketInternal (
140
- poolLimit int , timeout time.Duration , shouldBlock bool , poolTimeout time.Duration ,
141
- ) (socket * mongoSocket , abended bool , err error ) {
143
+ func (server * mongoServer ) acquireSocketInternal (info * DialInfo , shouldBlock bool ) (socket * mongoSocket , abended bool , err error ) {
142
144
for {
143
145
server .Lock ()
144
146
abended = server .abended
145
147
if server .closed {
146
148
server .Unlock ()
147
149
return nil , abended , errServerClosed
148
150
}
149
- if poolLimit > 0 {
151
+ if info . poolLimit () > 0 {
150
152
if shouldBlock {
151
153
// Beautiful. Golang conditions don't have a WaitWithTimeout, so I've implemented the timeout
152
154
// with a wait + broadcast. The broadcast will cause the loop here to re-check the timeout,
@@ -158,11 +160,11 @@ func (server *mongoServer) acquireSocketInternal(
158
160
// https://github.com/golang/go/issues/16620, since the lock needs to be held in _this_ goroutine.
159
161
waitDone := make (chan struct {})
160
162
timeoutHit := false
161
- if poolTimeout > 0 {
163
+ if info . PoolTimeout > 0 {
162
164
go func () {
163
165
select {
164
166
case <- waitDone :
165
- case <- time .After (poolTimeout ):
167
+ case <- time .After (info . PoolTimeout ):
166
168
// timeoutHit is part of the wait condition, so needs to be changed under mutex.
167
169
server .Lock ()
168
170
defer server .Unlock ()
@@ -172,7 +174,7 @@ func (server *mongoServer) acquireSocketInternal(
172
174
}()
173
175
}
174
176
timeSpentWaiting := time .Duration (0 )
175
- for len (server .liveSockets )- len (server .unusedSockets ) >= poolLimit && ! timeoutHit {
177
+ for len (server .liveSockets )- len (server .unusedSockets ) >= info . poolLimit () && ! timeoutHit {
176
178
// We only count time spent in Wait(), and not time evaluating the entire loop,
177
179
// so that in the happy non-blocking path where the condition above evaluates true
178
180
// first time, we record a nice round zero wait time.
@@ -191,7 +193,7 @@ func (server *mongoServer) acquireSocketInternal(
191
193
// Record that we fetched a connection of of a socket list and how long we spent waiting
192
194
stats .noticeSocketAcquisition (timeSpentWaiting )
193
195
} else {
194
- if len (server .liveSockets )- len (server .unusedSockets ) >= poolLimit {
196
+ if len (server .liveSockets )- len (server .unusedSockets ) >= info . poolLimit () {
195
197
server .Unlock ()
196
198
return nil , false , errPoolLimit
197
199
}
@@ -202,15 +204,15 @@ func (server *mongoServer) acquireSocketInternal(
202
204
socket = server .unusedSockets [n - 1 ]
203
205
server .unusedSockets [n - 1 ] = nil // Help GC.
204
206
server .unusedSockets = server .unusedSockets [:n - 1 ]
205
- info := server .info
207
+ serverInfo := server .info
206
208
server .Unlock ()
207
- err = socket .InitialAcquire (info , timeout )
209
+ err = socket .InitialAcquire (serverInfo , info )
208
210
if err != nil {
209
211
continue
210
212
}
211
213
} else {
212
214
server .Unlock ()
213
- socket , err = server .Connect (timeout )
215
+ socket , err = server .Connect (info )
214
216
if err == nil {
215
217
server .Lock ()
216
218
// We've waited for the Connect, see if we got
@@ -231,20 +233,18 @@ func (server *mongoServer) acquireSocketInternal(
231
233
232
234
// Connect establishes a new connection to the server. This should
233
235
// generally be done through server.AcquireSocket().
234
- func (server * mongoServer ) Connect (timeout time. Duration ) (* mongoSocket , error ) {
236
+ func (server * mongoServer ) Connect (info * DialInfo ) (* mongoSocket , error ) {
235
237
server .RLock ()
236
238
master := server .info .Master
237
239
dial := server .dial
238
240
server .RUnlock ()
239
241
240
- logf ("Establishing new connection to %s (timeout=%s)..." , server .Addr , timeout )
242
+ logf ("Establishing new connection to %s (timeout=%s)..." , server .Addr , info . Timeout )
241
243
var conn net.Conn
242
244
var err error
243
245
switch {
244
246
case ! dial .isSet ():
245
- // Cannot do this because it lacks timeout support. :-(
246
- //conn, err = net.DialTCP("tcp", nil, server.tcpaddr)
247
- conn , err = net .DialTimeout ("tcp" , server .ResolvedAddr , timeout )
247
+ conn , err = net .DialTimeout ("tcp" , server .ResolvedAddr , info .Timeout )
248
248
if tcpconn , ok := conn .(* net.TCPConn ); ok {
249
249
tcpconn .SetKeepAlive (true )
250
250
} else if err == nil {
@@ -264,7 +264,7 @@ func (server *mongoServer) Connect(timeout time.Duration) (*mongoSocket, error)
264
264
logf ("Connection to %s established." , server .Addr )
265
265
266
266
stats .conn (+ 1 , master )
267
- return newSocket (server , conn , timeout ), nil
267
+ return newSocket (server , conn , info ), nil
268
268
}
269
269
270
270
// Close forces closing all sockets that are alive, whether
0 commit comments