forked from TrueCloudLab/frostfs-node
[#938] ir/netmap: Call AddPeer method if existing candidate was updated
In previous implementation IR handler of `AddPeer` notification didn't send registration to contract if existing peer changed has changed its information. as a consequence, the network map members could not update the information without going into offline. Change `processAddPeer` handler to check if * candidate in the network map is a brand new * or information about the network map member was changed and call `AddPeer` method if so. Signed-off-by: Leonard Lyubich <leonard@nspcc.ru>
This commit is contained in:
parent
0ec8f529ab
commit
68565d9617
3 changed files with 66 additions and 34 deletions
|
@ -1,7 +1,9 @@
|
|||
package netmap
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"sync"
|
||||
|
||||
"github.com/nspcc-dev/neofs-api-go/pkg/netmap"
|
||||
|
@ -12,13 +14,19 @@ type (
|
|||
*sync.RWMutex
|
||||
enabled bool
|
||||
threshold uint64
|
||||
lastAccess map[string]epochStamp
|
||||
lastAccess map[string]epochStampWithNodeInfo
|
||||
}
|
||||
|
||||
epochStamp struct {
|
||||
epoch uint64
|
||||
removeFlag bool
|
||||
}
|
||||
|
||||
epochStampWithNodeInfo struct {
|
||||
epochStamp
|
||||
|
||||
binNodeInfo []byte
|
||||
}
|
||||
)
|
||||
|
||||
func newCleanupTable(enabled bool, threshold uint64) cleanupTable {
|
||||
|
@ -26,7 +34,7 @@ func newCleanupTable(enabled bool, threshold uint64) cleanupTable {
|
|||
RWMutex: new(sync.RWMutex),
|
||||
enabled: enabled,
|
||||
threshold: threshold,
|
||||
lastAccess: make(map[string]epochStamp),
|
||||
lastAccess: make(map[string]epochStampWithNodeInfo),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -36,33 +44,51 @@ func (c *cleanupTable) update(snapshot *netmap.Netmap, now uint64) {
|
|||
defer c.Unlock()
|
||||
|
||||
// replacing map is less memory efficient but faster
|
||||
newMap := make(map[string]epochStamp, len(snapshot.Nodes))
|
||||
newMap := make(map[string]epochStampWithNodeInfo, len(snapshot.Nodes))
|
||||
|
||||
for i := range snapshot.Nodes {
|
||||
keyString := hex.EncodeToString(snapshot.Nodes[i].PublicKey())
|
||||
if access, ok := c.lastAccess[keyString]; ok {
|
||||
access.removeFlag = false // reset remove Flag on each Update
|
||||
newMap[keyString] = access
|
||||
} else {
|
||||
newMap[keyString] = epochStamp{epoch: now}
|
||||
binNodeInfo, err := snapshot.Nodes[i].Marshal()
|
||||
if err != nil {
|
||||
panic(fmt.Errorf("could not marshal node info: %w", err)) // seems better than ignore
|
||||
}
|
||||
|
||||
keyString := hex.EncodeToString(snapshot.Nodes[i].PublicKey())
|
||||
|
||||
access, ok := c.lastAccess[keyString]
|
||||
if ok {
|
||||
access.removeFlag = false // reset remove Flag on each Update
|
||||
} else {
|
||||
access.epoch = now
|
||||
}
|
||||
|
||||
access.binNodeInfo = binNodeInfo
|
||||
|
||||
newMap[keyString] = access
|
||||
}
|
||||
|
||||
c.lastAccess = newMap
|
||||
}
|
||||
|
||||
func (c *cleanupTable) touch(keyString string, now uint64) bool {
|
||||
// updates last access time of the netmap node by string public key.
|
||||
//
|
||||
// Returns true if at least one condition is met:
|
||||
// * node hasn't been accessed yet;
|
||||
// * remove flag is set;
|
||||
// * binary node info has changed.
|
||||
func (c *cleanupTable) touch(keyString string, now uint64, binNodeInfo []byte) bool {
|
||||
c.Lock()
|
||||
defer c.Unlock()
|
||||
|
||||
access, ok := c.lastAccess[keyString]
|
||||
result := !access.removeFlag && ok
|
||||
result := !ok || access.removeFlag || !bytes.Equal(access.binNodeInfo, binNodeInfo)
|
||||
|
||||
access.removeFlag = false // reset remove flag on each touch
|
||||
if now > access.epoch {
|
||||
access.epoch = now
|
||||
}
|
||||
|
||||
access.binNodeInfo = binNodeInfo // update binary node info
|
||||
|
||||
c.lastAccess[keyString] = access
|
||||
|
||||
return result
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue