@@ -119,10 +119,14 @@ type pool struct {
119
119
// loop runs or waits. Its lock guards cancelBackgroundCtx, conns, and newConnWait. Any changes
120
120
// to the state of the guarded values must be made while holding the lock to prevent undefined
121
121
// behavior in the createConnections() waiting logic.
122
- createConnectionsCond * sync.Cond
123
- cancelBackgroundCtx context.CancelFunc // cancelBackgroundCtx is called to signal background goroutines to stop.
124
- conns map [int64 ]* connection // conns holds all currently open connections.
125
- newConnWait wantConnQueue // newConnWait holds all wantConn requests for new connections.
122
+ // createConnectionsCond *sync.Cond
123
+ createConnectionSem chan struct {}
124
+
125
+ connsMu sync.Mutex
126
+ backgroundCtx context.Context
127
+ cancelBackgroundCtx context.CancelFunc // cancelBackgroundCtx is called to signal background goroutines to stop.
128
+ conns map [int64 ]* connection // conns holds all currently open connections.
129
+ newConnWait wantConnQueue // newConnWait holds all wantConn requests for new connections.
126
130
127
131
idleMu sync.Mutex // idleMu guards idleConns, idleConnWait
128
132
idleConns []* connection // idleConns holds all idle connections.
@@ -210,24 +214,25 @@ func newPool(config poolConfig, connOpts ...ConnectionOption) *pool {
210
214
}
211
215
212
216
pool := & pool {
213
- address : config .Address ,
214
- minSize : config .MinPoolSize ,
215
- maxSize : config .MaxPoolSize ,
216
- maxConnecting : maxConnecting ,
217
- loadBalanced : config .LoadBalanced ,
218
- monitor : config .PoolMonitor ,
219
- logger : config .Logger ,
220
- handshakeErrFn : config .handshakeErrFn ,
221
- connOpts : connOpts ,
222
- generation : newPoolGenerationMap (),
223
- state : poolPaused ,
224
- maintainInterval : maintainInterval ,
225
- maintainReady : make (chan struct {}, 1 ),
226
- backgroundDone : & sync.WaitGroup {},
227
- createConnectionsCond : sync .NewCond (& sync.Mutex {}),
228
- conns : make (map [int64 ]* connection , config .MaxPoolSize ),
229
- idleConns : make ([]* connection , 0 , config .MaxPoolSize ),
230
- connectTimeout : config .ConnectTimeout ,
217
+ address : config .Address ,
218
+ minSize : config .MinPoolSize ,
219
+ maxSize : config .MaxPoolSize ,
220
+ maxConnecting : maxConnecting ,
221
+ loadBalanced : config .LoadBalanced ,
222
+ monitor : config .PoolMonitor ,
223
+ logger : config .Logger ,
224
+ handshakeErrFn : config .handshakeErrFn ,
225
+ connOpts : connOpts ,
226
+ generation : newPoolGenerationMap (),
227
+ state : poolPaused ,
228
+ maintainInterval : maintainInterval ,
229
+ maintainReady : make (chan struct {}, 1 ),
230
+ backgroundDone : & sync.WaitGroup {},
231
+ createConnectionSem : make (chan struct {}, maxConnecting ),
232
+ // createConnectionsCond: sync.NewCond(&sync.Mutex{}),
233
+ conns : make (map [int64 ]* connection , config .MaxPoolSize ),
234
+ idleConns : make ([]* connection , 0 , config .MaxPoolSize ),
235
+ connectTimeout : config .ConnectTimeout ,
231
236
}
232
237
// minSize must not exceed maxSize if maxSize is not 0
233
238
if pool .maxSize != 0 && pool .minSize > pool .maxSize {
@@ -240,19 +245,18 @@ func newPool(config poolConfig, connOpts ...ConnectionOption) *pool {
240
245
// Create a Context with cancellation that's used to signal the createConnections() and
241
246
// maintain() background goroutines to stop. Also create a "backgroundDone" WaitGroup that is
242
247
// used to wait for the background goroutines to return.
243
- var ctx context.Context
244
- ctx , pool .cancelBackgroundCtx = context .WithCancel (context .Background ())
248
+ pool .backgroundCtx , pool .cancelBackgroundCtx = context .WithCancel (context .Background ())
245
249
246
- for i := 0 ; i < int (pool .maxConnecting ); i ++ {
247
- pool .backgroundDone .Add (1 )
248
- go pool .createConnections (ctx , pool .backgroundDone )
249
- }
250
+ // for i := 0; i < int(pool.maxConnecting); i++ {
251
+ // pool.backgroundDone.Add(1)
252
+ // go pool.createConnections(ctx, pool.backgroundDone)
253
+ // }
250
254
251
255
// If maintainInterval is not positive, don't start the maintain() goroutine. Expect that
252
256
// negative values are only used in testing; this config value is not user-configurable.
253
257
if maintainInterval > 0 {
254
258
pool .backgroundDone .Add (1 )
255
- go pool .maintain (ctx , pool .backgroundDone )
259
+ go pool .maintain (pool . backgroundCtx , pool .backgroundDone )
256
260
}
257
261
258
262
if mustLogPoolMessage (pool ) {
@@ -343,10 +347,9 @@ func (p *pool) close(ctx context.Context) {
343
347
// condition by cancelling the "background goroutine" Context, even tho cancelling the Context
344
348
// is also synchronized by a lock. Otherwise, we run into an intermittent bug that prevents the
345
349
// createConnections() goroutines from exiting.
346
- p .createConnectionsCond . L .Lock ()
350
+ p .connsMu .Lock ()
347
351
p .cancelBackgroundCtx ()
348
- p .createConnectionsCond .Broadcast ()
349
- p .createConnectionsCond .L .Unlock ()
352
+ p .connsMu .Unlock ()
350
353
351
354
// Wait for all background goroutines to exit.
352
355
p .backgroundDone .Wait ()
@@ -402,7 +405,7 @@ func (p *pool) close(ctx context.Context) {
402
405
// Collect all conns from the pool and try to deliver ErrPoolClosed to any waiting wantConns
403
406
// from newConnWait while holding the createConnectionsCond lock. We can't call removeConnection
404
407
// on the connections while holding any locks, so do that after we release the lock.
405
- p .createConnectionsCond . L .Lock ()
408
+ p .connsMu .Lock ()
406
409
conns := make ([]* connection , 0 , len (p .conns ))
407
410
for _ , conn := range p .conns {
408
411
conns = append (conns , conn )
@@ -414,7 +417,7 @@ func (p *pool) close(ctx context.Context) {
414
417
}
415
418
w .tryDeliver (nil , ErrPoolClosed )
416
419
}
417
- p .createConnectionsCond . L .Unlock ()
420
+ p .connsMu .Unlock ()
418
421
419
422
if mustLogPoolMessage (p ) {
420
423
logPoolMessage (p , logger .ConnectionPoolClosed )
@@ -724,19 +727,19 @@ func (p *pool) removeConnection(conn *connection, reason reason, err error) erro
724
727
return ErrWrongPool
725
728
}
726
729
727
- p .createConnectionsCond . L .Lock ()
730
+ p .connsMu .Lock ()
728
731
_ , ok := p .conns [conn .driverConnectionID ]
729
732
if ! ok {
730
733
// If the connection has been removed from the pool already, exit without doing any
731
734
// additional state changes.
732
- p .createConnectionsCond . L .Unlock ()
735
+ p .connsMu .Unlock ()
733
736
return nil
734
737
}
735
738
delete (p .conns , conn .driverConnectionID )
736
739
// Signal the createConnectionsCond so any goroutines waiting for a new connection slot in the
737
740
// pool will proceed.
738
- p .createConnectionsCond .Signal ()
739
- p .createConnectionsCond . L .Unlock ()
741
+ // p.createConnectionsCond.Signal() // TODO: What do we do with this?
742
+ p .connsMu .Unlock ()
740
743
741
744
// Only update the generation numbers map if the connection has retrieved its generation number.
742
745
// Otherwise, we'd decrement the count for the generation even though it had never been
@@ -1029,7 +1032,7 @@ func (p *pool) clearImpl(err error, serviceID *bson.ObjectID, interruptAllConnec
1029
1032
1030
1033
p .removePerishedConns ()
1031
1034
if interruptAllConnections {
1032
- p .createConnectionsCond . L .Lock ()
1035
+ p .connsMu .Lock ()
1033
1036
p .idleMu .Lock ()
1034
1037
1035
1038
idleConns := make (map [* connection ]bool , len (p .idleConns ))
@@ -1045,7 +1048,7 @@ func (p *pool) clearImpl(err error, serviceID *bson.ObjectID, interruptAllConnec
1045
1048
}
1046
1049
1047
1050
p .idleMu .Unlock ()
1048
- p .createConnectionsCond . L .Unlock ()
1051
+ p .connsMu .Unlock ()
1049
1052
1050
1053
p .interruptConnections (conns )
1051
1054
}
@@ -1067,15 +1070,15 @@ func (p *pool) clearImpl(err error, serviceID *bson.ObjectID, interruptAllConnec
1067
1070
// Clear the new connections wait queue. This effectively pauses the createConnections()
1068
1071
// background goroutine because newConnWait is empty and checkOut() won't insert any more
1069
1072
// wantConns into newConnWait until the pool is marked "ready" again.
1070
- p .createConnectionsCond . L .Lock ()
1073
+ p .connsMu .Lock ()
1071
1074
for {
1072
1075
w := p .newConnWait .popFront ()
1073
1076
if w == nil {
1074
1077
break
1075
1078
}
1076
1079
w .tryDeliver (nil , pcErr )
1077
1080
}
1078
- p .createConnectionsCond . L .Unlock ()
1081
+ p .connsMu .Unlock ()
1079
1082
}
1080
1083
}
1081
1084
@@ -1121,17 +1124,19 @@ func (p *pool) getOrQueueForIdleConn(w *wantConn) bool {
1121
1124
}
1122
1125
1123
1126
func (p * pool ) queueForNewConn (w * wantConn ) {
1124
- p .createConnectionsCond . L .Lock ()
1125
- defer p .createConnectionsCond . L .Unlock ()
1127
+ p .connsMu .Lock ()
1128
+ defer p .connsMu .Unlock ()
1126
1129
1127
1130
p .newConnWait .cleanFront ()
1128
1131
p .newConnWait .pushBack (w )
1129
- p .createConnectionsCond .Signal ()
1132
+
1133
+ p .backgroundDone .Add (1 )
1134
+ go p .createConnection (p .backgroundCtx , p .backgroundDone )
1130
1135
}
1131
1136
1132
1137
func (p * pool ) totalConnectionCount () int {
1133
- p .createConnectionsCond . L .Lock ()
1134
- defer p .createConnectionsCond . L .Unlock ()
1138
+ p .connsMu .Lock ()
1139
+ defer p .connsMu .Unlock ()
1135
1140
1136
1141
return len (p .conns )
1137
1142
}
@@ -1144,35 +1149,37 @@ func (p *pool) availableConnectionCount() int {
1144
1149
}
1145
1150
1146
1151
// createConnections creates connections for wantConn requests on the newConnWait queue.
1147
- func (p * pool ) createConnections (ctx context.Context , wg * sync.WaitGroup ) {
1152
+ func (p * pool ) createConnection (ctx context.Context , wg * sync.WaitGroup ) {
1148
1153
defer wg .Done ()
1149
1154
1150
- // condition returns true if the createConnections() loop should continue and false if it should
1151
- // wait. Note that the condition also listens for Context cancellation, which also causes the
1152
- // loop to continue, allowing for a subsequent check to return from createConnections().
1153
- condition := func () bool {
1154
- checkOutWaiting := p .newConnWait .len () > 0
1155
- poolHasSpace := p .maxSize == 0 || uint64 (len (p .conns )) < p .maxSize
1156
- cancelled := ctx .Err () != nil
1157
- return (checkOutWaiting && poolHasSpace ) || cancelled
1158
- }
1159
-
1160
- // wait waits for there to be an available wantConn and for the pool to have space for a new
1161
- // connection. When the condition becomes true, it creates a new connection and returns the
1162
- // waiting wantConn and new connection. If the Context is cancelled or there are any
1163
- // errors, wait returns with "ok = false".
1164
- wait := func () (* wantConn , * connection , bool ) {
1165
- p .createConnectionsCond .L .Lock ()
1166
- defer p .createConnectionsCond .L .Unlock ()
1167
-
1168
- for ! condition () {
1169
- p .createConnectionsCond .Wait ()
1170
- }
1155
+ // TODO: Do we want to perma-block here? Seems like that could create a
1156
+ // bunch of waiting goroutines that will never complete until the pool
1157
+ // is disconnected.
1158
+ select {
1159
+ case p .createConnectionSem <- struct {}{}:
1160
+ defer func () {
1161
+ <- p .createConnectionSem
1162
+ }()
1163
+ case <- ctx .Done ():
1164
+ return
1165
+ case <- time .After (10 * time .Millisecond ):
1166
+ return
1167
+ }
1171
1168
1169
+ nextWaiter := func () (* wantConn , * connection , bool ) {
1170
+ p .connsMu .Lock ()
1171
+ defer p .connsMu .Unlock ()
1172
+
1173
+ // TODO: Do we need this check here?
1172
1174
if ctx .Err () != nil {
1173
1175
return nil , nil , false
1174
1176
}
1175
1177
1178
+ // TODO: Is this condition correct?
1179
+ if p .maxSize > 0 && uint64 (len (p .conns )) >= p .maxSize {
1180
+ return nil , nil , false
1181
+ }
1182
+
1176
1183
p .newConnWait .cleanFront ()
1177
1184
w := p .newConnWait .popFront ()
1178
1185
if w == nil {
@@ -1187,99 +1194,234 @@ func (p *pool) createConnections(ctx context.Context, wg *sync.WaitGroup) {
1187
1194
return w , conn , true
1188
1195
}
1189
1196
1190
- for ctx .Err () == nil {
1191
- w , conn , ok := wait ()
1192
- if ! ok {
1193
- continue
1194
- }
1195
-
1196
- if mustLogPoolMessage (p ) {
1197
- keysAndValues := logger.KeyValues {
1198
- logger .KeyDriverConnectionID , conn .driverConnectionID ,
1199
- }
1200
-
1201
- logPoolMessage (p , logger .ConnectionCreated , keysAndValues ... )
1202
- }
1197
+ w , conn , ok := nextWaiter ()
1198
+ if ! ok {
1199
+ return
1200
+ }
1203
1201
1204
- if p .monitor != nil {
1205
- p .monitor .Event (& event.PoolEvent {
1206
- Type : event .ConnectionCreated ,
1207
- Address : p .address .String (),
1208
- ConnectionID : conn .driverConnectionID ,
1209
- })
1202
+ if mustLogPoolMessage (p ) {
1203
+ keysAndValues := logger.KeyValues {
1204
+ logger .KeyDriverConnectionID , conn .driverConnectionID ,
1210
1205
}
1211
1206
1212
- start := time .Now ()
1213
- // Pass the createConnections context to connect to allow pool close to
1214
- // cancel connection establishment so shutdown doesn't block indefinitely if
1215
- // connectTimeout=0.
1216
- //
1217
- // Per the specifications, an explicit value of connectTimeout=0 means the
1218
- // timeout is "infinite".
1207
+ logPoolMessage (p , logger .ConnectionCreated , keysAndValues ... )
1208
+ }
1219
1209
1220
- var cancel context.CancelFunc
1210
+ if p .monitor != nil {
1211
+ p .monitor .Event (& event.PoolEvent {
1212
+ Type : event .ConnectionCreated ,
1213
+ Address : p .address .String (),
1214
+ ConnectionID : conn .driverConnectionID ,
1215
+ })
1216
+ }
1221
1217
1222
- connctx := context .Background ()
1223
- if p .connectTimeout != 0 {
1224
- connctx , cancel = context .WithTimeout (ctx , p .connectTimeout )
1225
- }
1218
+ start := time .Now ()
1219
+ // Pass the createConnections context to connect to allow pool close to
1220
+ // cancel connection establishment so shutdown doesn't block indefinitely if
1221
+ // connectTimeout=0.
1222
+ //
1223
+ // Per the specifications, an explicit value of connectTimeout=0 means the
1224
+ // timeout is "infinite".
1226
1225
1227
- err := conn . connect ( connctx )
1226
+ var cancel context. CancelFunc
1228
1227
1229
- if cancel != nil {
1230
- cancel ()
1231
- }
1228
+ connctx := context .Background ()
1229
+ if p .connectTimeout != 0 {
1230
+ connctx , cancel = context .WithTimeout (ctx , p .connectTimeout )
1231
+ }
1232
1232
1233
- if err != nil {
1234
- w .tryDeliver (nil , err )
1235
-
1236
- // If there's an error connecting the new connection, call the handshake error handler
1237
- // that implements the SDAM handshake error handling logic. This must be called after
1238
- // delivering the connection error to the waiting wantConn. If it's called before, the
1239
- // handshake error handler may clear the connection pool, leading to a different error
1240
- // message being delivered to the same waiting wantConn in idleConnWait when the wait
1241
- // queues are cleared.
1242
- if p .handshakeErrFn != nil {
1243
- p .handshakeErrFn (err , conn .generation , conn .desc .ServiceID )
1244
- }
1233
+ err := conn .connect (connctx )
1245
1234
1246
- _ = p .removeConnection (conn , reason {
1247
- loggerConn : logger .ReasonConnClosedError ,
1248
- event : event .ReasonError ,
1249
- }, err )
1235
+ if cancel != nil {
1236
+ cancel ()
1237
+ }
1250
1238
1251
- _ = p .closeConnection (conn )
1239
+ if err != nil {
1240
+ w .tryDeliver (nil , err )
1252
1241
1253
- continue
1242
+ // If there's an error connecting the new connection, call the handshake error handler
1243
+ // that implements the SDAM handshake error handling logic. This must be called after
1244
+ // delivering the connection error to the waiting wantConn. If it's called before, the
1245
+ // handshake error handler may clear the connection pool, leading to a different error
1246
+ // message being delivered to the same waiting wantConn in idleConnWait when the wait
1247
+ // queues are cleared.
1248
+ if p .handshakeErrFn != nil {
1249
+ p .handshakeErrFn (err , conn .generation , conn .desc .ServiceID )
1254
1250
}
1255
1251
1256
- duration := time .Since (start )
1257
- if mustLogPoolMessage (p ) {
1258
- keysAndValues := logger.KeyValues {
1259
- logger .KeyDriverConnectionID , conn .driverConnectionID ,
1260
- logger .KeyDurationMS , duration .Milliseconds (),
1261
- }
1252
+ _ = p .removeConnection (conn , reason {
1253
+ loggerConn : logger .ReasonConnClosedError ,
1254
+ event : event .ReasonError ,
1255
+ }, err )
1262
1256
1263
- logPoolMessage (p , logger .ConnectionReady , keysAndValues ... )
1264
- }
1257
+ _ = p .closeConnection (conn )
1265
1258
1266
- if p .monitor != nil {
1267
- p .monitor .Event (& event.PoolEvent {
1268
- Type : event .ConnectionReady ,
1269
- Address : p .address .String (),
1270
- ConnectionID : conn .driverConnectionID ,
1271
- Duration : duration ,
1272
- })
1273
- }
1259
+ return
1260
+ }
1274
1261
1275
- if w .tryDeliver (conn , nil ) {
1276
- continue
1262
+ duration := time .Since (start )
1263
+ if mustLogPoolMessage (p ) {
1264
+ keysAndValues := logger.KeyValues {
1265
+ logger .KeyDriverConnectionID , conn .driverConnectionID ,
1266
+ logger .KeyDurationMS , duration .Milliseconds (),
1277
1267
}
1278
1268
1279
- _ = p . checkInNoEvent ( conn )
1269
+ logPoolMessage ( p , logger . ConnectionReady , keysAndValues ... )
1280
1270
}
1271
+
1272
+ if p .monitor != nil {
1273
+ p .monitor .Event (& event.PoolEvent {
1274
+ Type : event .ConnectionReady ,
1275
+ Address : p .address .String (),
1276
+ ConnectionID : conn .driverConnectionID ,
1277
+ Duration : duration ,
1278
+ })
1279
+ }
1280
+
1281
+ if w .tryDeliver (conn , nil ) {
1282
+ return
1283
+ }
1284
+
1285
+ _ = p .checkInNoEvent (conn )
1281
1286
}
1282
1287
1288
+ // createConnections creates connections for wantConn requests on the newConnWait queue.
1289
+ // func (p *pool) createConnections(ctx context.Context, wg *sync.WaitGroup) {
1290
+ // defer wg.Done()
1291
+
1292
+ // // condition returns true if the createConnections() loop should continue and false if it should
1293
+ // // wait. Note that the condition also listens for Context cancellation, which also causes the
1294
+ // // loop to continue, allowing for a subsequent check to return from createConnections().
1295
+ // condition := func() bool {
1296
+ // checkOutWaiting := p.newConnWait.len() > 0
1297
+ // poolHasSpace := p.maxSize == 0 || uint64(len(p.conns)) < p.maxSize
1298
+ // cancelled := ctx.Err() != nil
1299
+ // return (checkOutWaiting && poolHasSpace) || cancelled
1300
+ // }
1301
+
1302
+ // // wait waits for there to be an available wantConn and for the pool to have space for a new
1303
+ // // connection. When the condition becomes true, it creates a new connection and returns the
1304
+ // // waiting wantConn and new connection. If the Context is cancelled or there are any
1305
+ // // errors, wait returns with "ok = false".
1306
+ // wait := func() (*wantConn, *connection, bool) {
1307
+ // p.createConnectionsCond.L.Lock()
1308
+ // defer p.createConnectionsCond.L.Unlock()
1309
+
1310
+ // for !condition() {
1311
+ // p.createConnectionsCond.Wait()
1312
+ // }
1313
+
1314
+ // if ctx.Err() != nil {
1315
+ // return nil, nil, false
1316
+ // }
1317
+
1318
+ // p.newConnWait.cleanFront()
1319
+ // w := p.newConnWait.popFront()
1320
+ // if w == nil {
1321
+ // return nil, nil, false
1322
+ // }
1323
+
1324
+ // conn := newConnection(p.address, p.connOpts...)
1325
+ // conn.pool = p
1326
+ // conn.driverConnectionID = atomic.AddInt64(&p.nextID, 1)
1327
+ // p.conns[conn.driverConnectionID] = conn
1328
+
1329
+ // return w, conn, true
1330
+ // }
1331
+
1332
+ // for ctx.Err() == nil {
1333
+ // w, conn, ok := wait()
1334
+ // if !ok {
1335
+ // continue
1336
+ // }
1337
+
1338
+ // if mustLogPoolMessage(p) {
1339
+ // keysAndValues := logger.KeyValues{
1340
+ // logger.KeyDriverConnectionID, conn.driverConnectionID,
1341
+ // }
1342
+
1343
+ // logPoolMessage(p, logger.ConnectionCreated, keysAndValues...)
1344
+ // }
1345
+
1346
+ // if p.monitor != nil {
1347
+ // p.monitor.Event(&event.PoolEvent{
1348
+ // Type: event.ConnectionCreated,
1349
+ // Address: p.address.String(),
1350
+ // ConnectionID: conn.driverConnectionID,
1351
+ // })
1352
+ // }
1353
+
1354
+ // start := time.Now()
1355
+ // // Pass the createConnections context to connect to allow pool close to
1356
+ // // cancel connection establishment so shutdown doesn't block indefinitely if
1357
+ // // connectTimeout=0.
1358
+ // //
1359
+ // // Per the specifications, an explicit value of connectTimeout=0 means the
1360
+ // // timeout is "infinite".
1361
+
1362
+ // var cancel context.CancelFunc
1363
+
1364
+ // connctx := context.Background()
1365
+ // if p.connectTimeout != 0 {
1366
+ // connctx, cancel = context.WithTimeout(ctx, p.connectTimeout)
1367
+ // }
1368
+
1369
+ // err := conn.connect(connctx)
1370
+
1371
+ // if cancel != nil {
1372
+ // cancel()
1373
+ // }
1374
+
1375
+ // if err != nil {
1376
+ // w.tryDeliver(nil, err)
1377
+
1378
+ // // If there's an error connecting the new connection, call the handshake error handler
1379
+ // // that implements the SDAM handshake error handling logic. This must be called after
1380
+ // // delivering the connection error to the waiting wantConn. If it's called before, the
1381
+ // // handshake error handler may clear the connection pool, leading to a different error
1382
+ // // message being delivered to the same waiting wantConn in idleConnWait when the wait
1383
+ // // queues are cleared.
1384
+ // if p.handshakeErrFn != nil {
1385
+ // p.handshakeErrFn(err, conn.generation, conn.desc.ServiceID)
1386
+ // }
1387
+
1388
+ // _ = p.removeConnection(conn, reason{
1389
+ // loggerConn: logger.ReasonConnClosedError,
1390
+ // event: event.ReasonError,
1391
+ // }, err)
1392
+
1393
+ // _ = p.closeConnection(conn)
1394
+
1395
+ // continue
1396
+ // }
1397
+
1398
+ // duration := time.Since(start)
1399
+ // if mustLogPoolMessage(p) {
1400
+ // keysAndValues := logger.KeyValues{
1401
+ // logger.KeyDriverConnectionID, conn.driverConnectionID,
1402
+ // logger.KeyDurationMS, duration.Milliseconds(),
1403
+ // }
1404
+
1405
+ // logPoolMessage(p, logger.ConnectionReady, keysAndValues...)
1406
+ // }
1407
+
1408
+ // if p.monitor != nil {
1409
+ // p.monitor.Event(&event.PoolEvent{
1410
+ // Type: event.ConnectionReady,
1411
+ // Address: p.address.String(),
1412
+ // ConnectionID: conn.driverConnectionID,
1413
+ // Duration: duration,
1414
+ // })
1415
+ // }
1416
+
1417
+ // if w.tryDeliver(conn, nil) {
1418
+ // continue
1419
+ // }
1420
+
1421
+ // _ = p.checkInNoEvent(conn)
1422
+ // }
1423
+ // }
1424
+
1283
1425
func (p * pool ) maintain (ctx context.Context , wg * sync.WaitGroup ) {
1284
1426
defer wg .Done ()
1285
1427
0 commit comments