Moved to atomics to detect if we have mapped subjects for an account since check for each inbound message.

If an account has many connections on a server under heavy load this could be contended.

Signed-off-by: Derek Collison <derek@nats.io>
This commit is contained in:
Derek Collison
2023-09-25 11:26:47 -07:00
parent 7ce47fd182
commit b70f874640
2 changed files with 10 additions and 15 deletions

View File

@@ -30,6 +30,7 @@ import (
"strconv"
"strings"
"sync"
"sync/atomic"
"time"
"github.com/nats-io/jwt/v2"
@@ -72,6 +73,7 @@ type Account struct {
lqws map[string]int32
usersRevoked map[string]int64
mappings []*mapping
hasMapped atomic.Bool
lmu sync.RWMutex
lleafs []*client
leafClusters map[string]uint64
@@ -291,6 +293,8 @@ func (a *Account) shallowCopy(na *Account) {
if len(na.mappings) > 0 && na.prand == nil {
na.prand = rand.New(rand.NewSource(time.Now().UnixNano()))
}
na.hasMapped.Store(len(na.mappings) > 0)
// JetStream
na.jsLimits = a.jsLimits
// Server config account limits.
@@ -703,6 +707,7 @@ func (a *Account) AddWeightedMappings(src string, dests ...*MapDest) error {
}
// If we did not replace add to the end.
a.mappings = append(a.mappings, m)
a.hasMapped.Store(len(a.mappings) > 0)
// If we have connected leafnodes make sure to update.
if a.nleafs > 0 {
@@ -729,6 +734,7 @@ func (a *Account) RemoveMapping(src string) bool {
a.mappings[i] = a.mappings[len(a.mappings)-1]
a.mappings[len(a.mappings)-1] = nil // gc
a.mappings = a.mappings[:len(a.mappings)-1]
a.hasMapped.Store(len(a.mappings) > 0)
return true
}
}
@@ -740,28 +746,17 @@ func (a *Account) hasMappings() bool {
if a == nil {
return false
}
a.mu.RLock()
hm := a.hasMappingsLocked()
a.mu.RUnlock()
return hm
}
// Indicates we have mapping entries.
// The account has been verified to be non-nil.
// Read or Write lock held on entry.
func (a *Account) hasMappingsLocked() bool {
return len(a.mappings) > 0
return a.hasMapped.Load()
}
// This performs the logic to map to a new dest subject based on mappings.
// Should only be called from processInboundClientMsg or service import processing.
func (a *Account) selectMappedSubject(dest string) (string, bool) {
a.mu.RLock()
if len(a.mappings) == 0 {
a.mu.RUnlock()
if !a.hasMappings() {
return dest, false
}
a.mu.RLock()
// In case we have to tokenize for subset matching.
tsa := [32]string{}
tts := tsa[:0]

View File

@@ -983,7 +983,7 @@ func (s *Server) processClientOrLeafAuthentication(c *client, opts *Options) (au
acc.mu.RLock()
c.Debugf("Authenticated JWT: %s %q (claim-name: %q, claim-tags: %q) "+
"signed with %q by Account %q (claim-name: %q, claim-tags: %q) signed with %q has mappings %t accused %p",
c.kindString(), juc.Subject, juc.Name, juc.Tags, juc.Issuer, issuer, acc.nameTag, acc.tags, acc.Issuer, acc.hasMappingsLocked(), acc)
c.kindString(), juc.Subject, juc.Name, juc.Tags, juc.Issuer, issuer, acc.nameTag, acc.tags, acc.Issuer, acc.hasMappings(), acc)
acc.mu.RUnlock()
return true
}