@@ -129,7 +129,7 @@ type ConnPool[C Connection] struct {
129
129
// workers is a waitgroup for all the currently running worker goroutines
130
130
workers sync.WaitGroup
131
131
close chan struct {}
132
- capacityMu sync.Mutex
132
+ capacityMu sync.RWMutex
133
133
134
134
config struct {
135
135
// connect is the callback to create a new connection for the pool
@@ -430,18 +430,40 @@ func (pool *ConnPool[C]) tryReturnConn(conn *Pooled[C]) bool {
430
430
if pool .wait .tryReturnConn (conn ) {
431
431
return true
432
432
}
433
- if pool .closeOnIdleLimitReached (conn ) {
433
+
434
+ for {
435
+ if pool .capacity .Load () < pool .active .Load () {
436
+ conn .Close ()
437
+ pool .closedConn ()
438
+ return true
439
+ }
440
+
441
+ if pool .closeOnIdleLimitReached (conn ) {
442
+ return false
443
+ }
444
+
445
+ if ! pool .capacityMu .TryRLock () {
446
+ // If we can't get a read lock here, it means that the pool is being closed. Retry and check `capacity` again.
447
+ continue
448
+ }
449
+ defer pool .capacityMu .RUnlock ()
450
+
451
+ if pool .capacity .Load () < pool .active .Load () {
452
+ conn .Close ()
453
+ pool .closedConn ()
454
+ return true
455
+ }
456
+
457
+ connSetting := conn .Conn .Setting ()
458
+ if connSetting == nil {
459
+ pool .clean .Push (conn )
460
+ } else {
461
+ stack := connSetting .bucket & stackMask
462
+ pool .settings [stack ].Push (conn )
463
+ pool .freshSettingsStack .Store (int64 (stack ))
464
+ }
434
465
return false
435
466
}
436
- connSetting := conn .Conn .Setting ()
437
- if connSetting == nil {
438
- pool .clean .Push (conn )
439
- } else {
440
- stack := connSetting .bucket & stackMask
441
- pool .settings [stack ].Push (conn )
442
- pool .freshSettingsStack .Store (int64 (stack ))
443
- }
444
- return false
445
467
}
446
468
447
469
func (pool * ConnPool [C ]) pop (stack * connStack [C ]) * Pooled [C ] {
@@ -595,7 +617,9 @@ func (pool *ConnPool[C]) get(ctx context.Context) (*Pooled[C], error) {
595
617
// to other clients, wait until one of the connections is returned
596
618
if conn == nil {
597
619
start := time .Now ()
598
- conn , err = pool .wait .waitForConn (ctx , nil )
620
+ conn , err = pool .wait .waitForConn (ctx , nil , func () bool {
621
+ return pool .close == nil || pool .capacity .Load () == 0
622
+ })
599
623
if err != nil {
600
624
return nil , ErrTimeout
601
625
}
@@ -652,7 +676,9 @@ func (pool *ConnPool[C]) getWithSetting(ctx context.Context, setting *Setting) (
652
676
// wait for one of them
653
677
if conn == nil {
654
678
start := time .Now ()
655
- conn , err = pool .wait .waitForConn (ctx , setting )
679
+ conn , err = pool .wait .waitForConn (ctx , setting , func () bool {
680
+ return pool .close == nil || pool .capacity .Load () == 0
681
+ })
656
682
if err != nil {
657
683
return nil , ErrTimeout
658
684
}
0 commit comments