Skip to content

Commit b1764d5

Browse files
committed
[CLIENT-1495] Tentatively check if a connection is allowed to avoid launching too many goroutines
1 parent 803ba4a commit b1764d5

File tree

2 files changed

+36
-2
lines changed

2 files changed

+36
-2
lines changed

CHANGELOG.md

+4
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,10 @@
77

88
- Allows reading of boolean types from the server, supported in Aerospike server v5.6. The current client will not support writing boolean type to the server. That features will be supported in the upcoming Go client v5.
99

10+
* **Fixes**
11+
12+
- [CLIENT-1495] Tentatively check if a connection is allowed to avoid launching too many goroutines.
13+
1014
* **Fixes**
1115

1216
- Implements correct and re-triable Scans for the Reflection API.

node.go

+32-2
Original file line numberDiff line numberDiff line change
@@ -541,6 +541,33 @@ func (nd *Node) getConnection(deadline time.Time, timeout time.Duration) (conn *
541541
return nd.getConnectionWithHint(deadline, timeout, 0)
542542
}
543543

544+
// newConnectionAllowed will tentatively check if the client is allowed to make a new connection
545+
// based on the ClientPolicy passed to it.
546+
// This is more or less a copy of the logic in the beginning of newConnection function.
547+
func (nd *Node) newConnectionAllowed() error {
548+
if !nd.active.Get() {
549+
return types.ErrServerNotAvailable
550+
}
551+
552+
// if connection count is limited and enough connections are already created, don't create a new one
553+
cc := nd.connectionCount.IncrementAndGet()
554+
defer nd.connectionCount.DecrementAndGet()
555+
if nd.cluster.clientPolicy.LimitConnectionsToQueueSize && cc > nd.cluster.clientPolicy.ConnectionQueueSize {
556+
return types.ErrTooManyConnectionsForNode
557+
}
558+
559+
// Check for opening connection threshold
560+
if nd.cluster.clientPolicy.OpeningConnectionThreshold > 0 {
561+
ct := nd.cluster.connectionThreshold.IncrementAndGet()
562+
defer nd.cluster.connectionThreshold.DecrementAndGet()
563+
if ct > nd.cluster.clientPolicy.OpeningConnectionThreshold {
564+
return types.ErrTooManyOpeningConnections
565+
}
566+
}
567+
568+
return nil
569+
}
570+
544571
// newConnection will make a new connection for the node.
545572
func (nd *Node) newConnection(overrideThreshold bool) (*Connection, error) {
546573
if !nd.active.Get() {
@@ -581,7 +608,7 @@ func (nd *Node) newConnection(overrideThreshold bool) (*Connection, error) {
581608

582609
// need to authenticate
583610
if err = conn.login(&nd.cluster.clientPolicy, nd.cluster.Password(), nd.sessionToken()); err != nil {
584-
// increment node errors if authenitocation hit a network error
611+
// increment node errors if authentication hit a network error
585612
if networkError(err) {
586613
nd.incrErrorCount()
587614
}
@@ -627,7 +654,10 @@ func (nd *Node) getConnectionWithHint(deadline time.Time, timeout time.Duration,
627654
}
628655

629656
if conn == nil {
630-
go nd.makeConnectionForPool(hint)
657+
// tentatively check if a connection is allowed to avoid launching too many goroutines.
658+
if err = nd.newConnectionAllowed(); err == nil {
659+
go nd.makeConnectionForPool(hint)
660+
}
631661
return nil, types.ErrConnectionPoolEmpty
632662
}
633663

0 commit comments

Comments
 (0)