Add network map hash to avoid unnecessary updates

This commit is contained in:
bcmmbaga
2024-06-26 16:29:10 +03:00
parent 628673db20
commit 7a0dc10ccc
6 changed files with 44 additions and 6 deletions

View File

@@ -167,6 +167,8 @@ type DefaultAccountManager struct {
userDeleteFromIDPEnabled bool
integratedPeerValidator integrated_validator.IntegratedValidator
networkMapHash map[string]uint64
}
// Settings represents Account settings structure that can be modified via API and Dashboard

View File

@@ -40,9 +40,9 @@ type Network struct {
Dns string
// Serial is an ID that increments by 1 when any change to the network happened (e.g. new peer has been added).
// Used to synchronize state to the client apps.
Serial uint64
Serial uint64 `hash:"ignore"`
mu sync.Mutex `json:"-" gorm:"-"`
mu sync.Mutex `json:"-" gorm:"-" hash:"ignore"`
}
// NewNetwork creates a new Network initializing it with a Serial=0

View File

@@ -6,6 +6,7 @@ import (
"strings"
"time"
"github.com/mitchellh/hashstructure/v2"
"github.com/netbirdio/netbird/management/server/posture"
"github.com/rs/xid"
log "github.com/sirupsen/logrus"
@@ -915,6 +916,18 @@ func updatePeerMeta(peer *nbpeer.Peer, meta nbpeer.PeerSystemMeta, account *Acco
// updateAccountPeers updates all peers that belong to an account.
// Should be called when changes have to be synced to peers.
func (am *DefaultAccountManager) updateAccountPeers(account *Account) {
start := time.Now()
var skipUpdate int
defer func() {
duration := time.Since(start)
log.Printf("Finished execution of updateAccountPeers, took %v\n", duration)
log.Println("not updated peers: ", skipUpdate)
}()
if am.networkMapHash == nil {
am.networkMapHash = map[string]uint64{}
}
peers := account.GetPeers()
approvedPeersMap, err := am.GetValidatedPeers(account)
@@ -922,14 +935,32 @@ func (am *DefaultAccountManager) updateAccountPeers(account *Account) {
log.Errorf("failed send out updates to peers, failed to validate peer: %v", err)
return
}
for _, peer := range peers {
if !am.peersUpdateManager.HasChannel(peer.ID) {
log.Tracef("peer %s doesn't have a channel, skipping network map update", peer.ID)
continue
//if !am.peersUpdateManager.HasChannel(peer.ID) {
// log.Tracef("peer %s doesn't have a channel, skipping network map update", peer.ID)
// continue
//}
remotePeerNetworkMap := account.GetPeerNetworkMap(peer.ID, am.dnsDomain, approvedPeersMap)
hash, err := hashstructure.Hash(remotePeerNetworkMap, hashstructure.FormatV2, &hashstructure.HashOptions{
ZeroNil: true,
IgnoreZeroValue: true,
SlicesAsSets: true,
UseStringer: true,
})
if err != nil {
log.Errorf("failed to generate network map hash: %v", err)
} else {
if am.networkMapHash[peer.ID] == hash {
log.Debugf("not sending network map update to peer: %s as there is nothing new", peer.ID)
skipUpdate++
continue
}
am.networkMapHash[peer.ID] = hash
}
postureChecks := am.getPeerPostureChecks(account, peer)
remotePeerNetworkMap := account.GetPeerNetworkMap(peer.ID, am.dnsDomain, approvedPeersMap)
update := toSyncResponse(nil, peer, nil, remotePeerNetworkMap, am.GetDNSDomain(), postureChecks)
am.peersUpdateManager.SendUpdate(peer.ID, &UpdateMessage{Update: update})
}

View File

@@ -47,6 +47,8 @@ type Peer struct {
Ephemeral bool
// Geo location based on connection IP
Location Location `gorm:"embedded;embeddedPrefix:location_"`
NetworkMapHash uint64 `hash:"ignore"`
}
type PeerStatus struct { //nolint:revive