@@ -3,6 +3,7 @@ package pool
3
3
import (
4
4
"context"
5
5
"errors"
6
+ "fmt"
6
7
"log"
7
8
"net"
8
9
"sync"
@@ -102,7 +103,7 @@ type ConnPool struct {
102
103
conns []* Conn
103
104
idleConns []* Conn
104
105
105
- poolSize int
106
+ poolSize atomic. Int32
106
107
idleConnsLen int
107
108
108
109
stats Stats
@@ -140,16 +141,16 @@ func (p *ConnPool) checkMinIdleConns() {
140
141
141
142
// Only create idle connections if we haven't reached the total pool size limit
142
143
// MinIdleConns should be a subset of PoolSize, not additional connections
143
- for p .poolSize < p .cfg .PoolSize && p .idleConnsLen < p .cfg .MinIdleConns {
144
+ for p .poolSize . Load () < int32 ( p .cfg .PoolSize ) && p .idleConnsLen < p .cfg .MinIdleConns {
144
145
select {
145
146
case p .queue <- struct {}{}:
146
- p .poolSize ++
147
+ p .poolSize . Add ( 1 )
147
148
p .idleConnsLen ++
148
149
go func () {
149
150
err := p .addIdleConn ()
150
151
if err != nil && err != ErrClosed {
151
152
p .connsMu .Lock ()
152
- p .poolSize --
153
+ p .poolSize . Add ( - 1 )
153
154
p .idleConnsLen --
154
155
p .connsMu .Unlock ()
155
156
}
@@ -197,7 +198,7 @@ func (p *ConnPool) newConn(ctx context.Context, pooled bool) (*Conn, error) {
197
198
}
198
199
199
200
p .connsMu .Lock ()
200
- if p .cfg .MaxActiveConns > 0 && p .poolSize >= p .cfg .MaxActiveConns {
201
+ if p .cfg .MaxActiveConns > 0 && p .poolSize . Load () >= int32 ( p .cfg .MaxActiveConns ) {
201
202
p .connsMu .Unlock ()
202
203
return nil , ErrPoolExhausted
203
204
}
@@ -214,18 +215,20 @@ func (p *ConnPool) newConn(ctx context.Context, pooled bool) (*Conn, error) {
214
215
p .connsMu .Lock ()
215
216
defer p .connsMu .Unlock ()
216
217
217
- if p .cfg .MaxActiveConns > 0 && p .poolSize >= p .cfg .MaxActiveConns {
218
+ if p .cfg .MaxActiveConns > 0 && p .poolSize . Load () >= int32 ( p .cfg .MaxActiveConns ) {
218
219
_ = cn .Close ()
219
220
return nil , ErrPoolExhausted
220
221
}
221
222
222
223
p .conns = append (p .conns , cn )
223
224
if pooled {
224
225
// If pool is full remove the cn on next Put.
225
- if p .poolSize >= p .cfg .PoolSize {
226
+ currentPoolSize := p .poolSize .Load ()
227
+ if currentPoolSize >= int32 (p .cfg .PoolSize ) {
228
+ fmt .Printf ("Conn %d poolSize (%d) >= cfg.PoolSize (%d), setting pooled to false\n " , cn .GetID (), currentPoolSize , p .cfg .PoolSize )
226
229
cn .pooled = false
227
230
} else {
228
- p .poolSize ++
231
+ p .poolSize . Add ( 1 )
229
232
}
230
233
}
231
234
@@ -314,9 +317,12 @@ func (p *ConnPool) getConn(ctx context.Context, isPubSub bool) (*Conn, error) {
314
317
return nil , ErrClosed
315
318
}
316
319
317
- //if err := p.waitTurn(ctx); err != nil {
318
- //return nil, err
319
- // }
320
+ // if it is not a pubsub connection, we need to wait for a turn
321
+ if ! isPubSub {
322
+ if err := p .waitTurn (ctx ); err != nil {
323
+ return nil , err
324
+ }
325
+ }
320
326
321
327
tries := 0
322
328
now := time .Now ()
@@ -331,7 +337,10 @@ func (p *ConnPool) getConn(ctx context.Context, isPubSub bool) (*Conn, error) {
331
337
p .connsMu .Unlock ()
332
338
333
339
if err != nil {
334
- //p.freeTurn()
340
+ if ! isPubSub {
341
+ p .freeTurn ()
342
+ }
343
+
335
344
return nil , err
336
345
}
337
346
@@ -340,6 +349,7 @@ func (p *ConnPool) getConn(ctx context.Context, isPubSub bool) (*Conn, error) {
340
349
}
341
350
342
351
if ! p .isHealthyConn (cn , now ) {
352
+ fmt .Printf ("Conn %d is not healthy, closing...\n " , cn .GetID ())
343
353
_ = p .CloseConn (cn )
344
354
continue
345
355
}
@@ -348,6 +358,7 @@ func (p *ConnPool) getConn(ctx context.Context, isPubSub bool) (*Conn, error) {
348
358
// Fast path: check processor existence once and cache the result
349
359
if processor := p .cfg .ConnectionProcessor ; processor != nil {
350
360
if err := processor .ProcessConnectionOnGet (ctx , cn ); err != nil {
361
+ fmt .Printf ("Conn %d failed processor on get, closing...\n " , cn .GetID ())
351
362
// Failed to process connection, discard it
352
363
_ = p .CloseConn (cn )
353
364
continue
@@ -357,20 +368,25 @@ func (p *ConnPool) getConn(ctx context.Context, isPubSub bool) (*Conn, error) {
357
368
atomic .AddUint32 (& p .stats .Hits , 1 )
358
369
cn .isPubSub = isPubSub
359
370
if isPubSub {
371
+ cn .pooled = false
372
+ p .poolSize .Add (- 1 )
360
373
atomic .AddUint32 (& p .stats .PubSubCount , 1 )
361
374
}
362
375
return cn , nil
363
376
}
364
377
365
378
atomic .AddUint32 (& p .stats .Misses , 1 )
366
379
367
- newcn , err := p .newConn (ctx , true )
380
+ newcn , err := p .newConn (ctx , ! isPubSub )
368
381
if err != nil {
369
- //p.freeTurn()
382
+ if ! isPubSub {
383
+ p .freeTurn ()
384
+ }
370
385
return nil , err
371
386
}
372
- newcn . isPubSub = isPubSub
387
+
373
388
if isPubSub {
389
+ newcn .isPubSub = true
374
390
atomic .AddUint32 (& p .stats .PubSubCount , 1 )
375
391
}
376
392
return newcn , nil
@@ -449,6 +465,8 @@ func (p *ConnPool) popIdle() (*Conn, error) {
449
465
if cn .IsUsable () {
450
466
p .idleConnsLen --
451
467
break
468
+ } else {
469
+ fmt .Printf ("Connection %d is not usable, retrying...\n " , cn .GetID ())
452
470
}
453
471
454
472
// Connection is not usable, put it back in the pool
@@ -478,6 +496,7 @@ func (p *ConnPool) Put(ctx context.Context, cn *Conn) {
478
496
shouldRemove := false
479
497
var err error
480
498
if cn .isPubSub {
499
+ fmt .Printf ("Conn %d is pubsub, removing...\n " , cn .GetID ())
481
500
p .Remove (ctx , cn , err )
482
501
return
483
502
}
@@ -492,19 +511,23 @@ func (p *ConnPool) Put(ctx context.Context, cn *Conn) {
492
511
}
493
512
}
494
513
514
+ fmt .Printf ("Conn %d shouldPool: %v, shouldRemove: %v\n " , cn .GetID (), shouldPool , shouldRemove )
495
515
// If processor says to remove the connection, do so
496
516
if shouldRemove {
517
+ fmt .Printf ("Conn %d shouldRemove, removing...\n " , cn .GetID ())
497
518
p .Remove (ctx , cn , nil )
498
519
return
499
520
}
500
521
501
522
// If processor says not to pool the connection, remove it
502
523
if ! shouldPool {
524
+ fmt .Printf ("Conn %d !shouldPool, removing...\n " , cn .GetID ())
503
525
p .Remove (ctx , cn , nil )
504
526
return
505
527
}
506
528
507
529
if ! cn .pooled {
530
+ fmt .Printf ("Conn %d !cn.pooled, removing...\n " , cn .GetID ())
508
531
p .Remove (ctx , cn , nil )
509
532
return
510
533
}
@@ -517,15 +540,17 @@ func (p *ConnPool) Put(ctx context.Context, cn *Conn) {
517
540
p .idleConns = append (p .idleConns , cn )
518
541
p .idleConnsLen ++
519
542
} else {
543
+ fmt .Printf ("Conn %d p.idleConnsLen >= p.cfg.MaxIdleConns, removing...\n " , cn .GetID ())
520
544
p .removeConn (cn )
521
545
shouldCloseConn = true
522
546
}
523
547
524
548
p .connsMu .Unlock ()
525
549
526
- // p.freeTurn()
550
+ p .freeTurn ()
527
551
528
552
if shouldCloseConn {
553
+ fmt .Printf ("Conn %d shouldCloseConn, closing...\n " , cn .GetID ())
529
554
_ = p .closeConn (cn )
530
555
}
531
556
}
@@ -552,7 +577,7 @@ func (p *ConnPool) removeConn(cn *Conn) {
552
577
if c == cn {
553
578
p .conns = append (p .conns [:i ], p .conns [i + 1 :]... )
554
579
if cn .pooled {
555
- p .poolSize --
580
+ p .poolSize . Add ( - 1 )
556
581
// Immediately check for minimum idle connections when a pooled connection is removed
557
582
p .checkMinIdleConns ()
558
583
}
@@ -634,7 +659,7 @@ func (p *ConnPool) Close() error {
634
659
}
635
660
}
636
661
p .conns = nil
637
- p .poolSize = 0
662
+ p .poolSize . Store ( 0 )
638
663
p .idleConns = nil
639
664
p .idleConnsLen = 0
640
665
p .connsMu .Unlock ()
0 commit comments