From 67bdd195600cde0512bbbbaab853ef3b4d0fb9a4 Mon Sep 17 00:00:00 2001 From: Nils Enkelmann Date: Fri, 28 Mar 2025 13:48:06 +0100 Subject: [PATCH] Rework to ensure transactional consistency in PeerChangedResponse again --- hscontrol/db/node.go | 19 +++++++++++++++++++ hscontrol/mapper/mapper.go | 37 +++++++++++++++---------------------- 2 files changed, 34 insertions(+), 22 deletions(-) diff --git a/hscontrol/db/node.go b/hscontrol/db/node.go index f36f66b7..1b9d5408 100644 --- a/hscontrol/db/node.go +++ b/hscontrol/db/node.go @@ -77,6 +77,25 @@ func ListNodes(tx *gorm.DB) (types.Nodes, error) { return nodes, nil } +func (hsdb *HSDatabase) ListNodesSubset(nodeIDs types.NodeIDs) (types.Nodes, error) { + return Read(hsdb.DB, func(rx *gorm.DB) (types.Nodes, error) { + return ListNodesSubset(rx, nodeIDs) + }) +} + +func ListNodesSubset(tx *gorm.DB, nodeIDs types.NodeIDs) (types.Nodes, error) { + nodes := types.Nodes{} + if err := tx. + Preload("AuthKey"). + Preload("AuthKey.User"). + Preload("User"). + Where(nodeIDs).Find(&nodes).Error; err != nil { + return nil, err + } + + return nodes, nil +} + func (hsdb *HSDatabase) ListEphemeralNodes() (types.Nodes, error) { return Read(hsdb.DB, func(rx *gorm.DB) (types.Nodes, error) { nodes := types.Nodes{} diff --git a/hscontrol/mapper/mapper.go b/hscontrol/mapper/mapper.go index cc048712..80d6c721 100644 --- a/hscontrol/mapper/mapper.go +++ b/hscontrol/mapper/mapper.go @@ -3,9 +3,7 @@ package mapper import ( "encoding/binary" "encoding/json" - "errors" "fmt" - "gorm.io/gorm" "io/fs" "net/url" "os" @@ -263,28 +261,20 @@ func (m *Mapper) PeerChangedResponse( var changedIDs []types.NodeID for nodeID, nodeChanged := range changed { if nodeChanged { - changedIDs = append(changedIDs, nodeID) + if nodeID != node.ID { + changedIDs = append(changedIDs, nodeID) + } } else { removedIDs = append(removedIDs, nodeID.NodeID()) } } - changedNodes := make(types.Nodes, 0, len(changedIDs)) - for _, changedID := range changedIDs { - if changedID != node.ID { - changedNode, err := m.GetNode(changedID) - if err != nil { - if errors.Is(err, gorm.ErrRecordNotFound) { - continue - } else { - return nil, err - } - } - changedNodes = append(changedNodes, changedNode) - } + changedNodes, err := m.ListNodesSubset(changedIDs) + if err != nil { + return nil, err } - err := appendPeerChanges( + err = appendPeerChanges( &resp, false, // partial change m.polMan, @@ -501,15 +491,18 @@ func (m *Mapper) ListPeers(nodeID types.NodeID) (types.Nodes, error) { return peers, nil } -func (m *Mapper) GetNode(nodeID types.NodeID) (*types.Node, error) { - node, err := m.db.GetNodeByID(nodeID) +func (m *Mapper) ListNodesSubset(nodeIDs []types.NodeID) (types.Nodes, error) { + nodes, err := m.db.ListNodesSubset(nodeIDs) if err != nil { return nil, err } - online := m.notif.IsLikelyConnected(node.ID) - node.IsOnline = &online - return node, nil + for _, node := range nodes { + online := m.notif.IsLikelyConnected(node.ID) + node.IsOnline = &online + } + + return nodes, nil } func nodeMapToList(nodes map[uint64]*types.Node) types.Nodes {