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
No known key found for this signature in database
GPG Key ID: 7249A19D20613553
6 changed files with 44 additions and 6 deletions

1
go.mod
View File

@ -70,6 +70,7 @@ require (
github.com/rs/xid v1.3.0
github.com/shirou/gopsutil/v3 v3.24.4
github.com/skratchdot/open-golang v0.0.0-20200116055534-eef842397966
github.com/spaolacci/murmur3 v1.1.0
github.com/stretchr/testify v1.9.0
github.com/testcontainers/testcontainers-go v0.31.0
github.com/testcontainers/testcontainers-go/modules/postgres v0.31.0

2
go.sum
View File

@ -439,6 +439,8 @@ github.com/smartystreets/assertions v1.13.0 h1:Dx1kYM01xsSqKPno3aqLnrwac2LetPvN2
github.com/smartystreets/assertions v1.13.0/go.mod h1:wDmR7qL282YbGsPy6H/yAsesrxfxaaSlJazyFLYVFx8=
github.com/smartystreets/goconvey v1.7.2 h1:9RBaZCeXEQ3UselpuwUQHltGVXvdwm6cv1hgR6gDIPg=
github.com/smartystreets/goconvey v1.7.2/go.mod h1:Vw0tHAZW6lzCRk3xgdin6fKYcG+G3Pg9vgXWeJpQFMM=
github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI=
github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ=
github.com/spf13/cast v1.5.0 h1:rj3WzYc11XZaIZMPKmwP96zkFEnnAmV8s6XbB2aY32w=
github.com/spf13/cast v1.5.0/go.mod h1:SpXXQ5YoyJw6s3/6cMTQuxvgRl3PCJiyaX9p6b155UU=

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