Fix nasty bug when graph action may not have been executed in some
branches
This commit is contained in:
parent
11904e1137
commit
770c7686ba
@ -38,6 +38,8 @@ type node struct {
|
|||||||
lastSeen time.Time
|
lastSeen time.Time
|
||||||
// lastSync keeps track of node last sync request
|
// lastSync keeps track of node last sync request
|
||||||
lastSync time.Time
|
lastSync time.Time
|
||||||
|
// errCount tracks error count when communicating with peer
|
||||||
|
errCount int
|
||||||
}
|
}
|
||||||
|
|
||||||
// Id is node ide
|
// Id is node ide
|
||||||
@ -71,15 +73,17 @@ func (n *node) walk(until func(peer *node) bool, action func(parent, peer *node)
|
|||||||
for queue.Len() > 0 {
|
for queue.Len() > 0 {
|
||||||
// pop the node from the front of the queue
|
// pop the node from the front of the queue
|
||||||
qnode := queue.Front()
|
qnode := queue.Front()
|
||||||
|
//fmt.Printf("qnodeValue: %v\n", qnode.Value.(*node))
|
||||||
if until(qnode.Value.(*node)) {
|
if until(qnode.Value.(*node)) {
|
||||||
return visited
|
return visited
|
||||||
}
|
}
|
||||||
// iterate through all of the node peers
|
// iterate through all of the node peers
|
||||||
// mark the visited nodes; enqueue the non-visted
|
// mark the visited nodes; enqueue the non-visted
|
||||||
for id, peer := range qnode.Value.(*node).peers {
|
for id, peer := range qnode.Value.(*node).peers {
|
||||||
|
action(qnode.Value.(*node), peer)
|
||||||
if _, ok := visited[id]; !ok {
|
if _, ok := visited[id]; !ok {
|
||||||
visited[id] = peer
|
visited[id] = peer
|
||||||
action(qnode.Value.(*node), peer)
|
//action(qnode.Value.(*node), peer)
|
||||||
queue.PushBack(peer)
|
queue.PushBack(peer)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -229,7 +233,25 @@ func (n *node) DeletePeerNode(id string) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// PruneStalePeerNodes prune the peers that have not been seen for longer than given time
|
// PrunePeer prunes the peers with the given id
|
||||||
|
func (n *node) PrunePeer(id string) {
|
||||||
|
n.Lock()
|
||||||
|
defer n.Unlock()
|
||||||
|
|
||||||
|
untilNoMorePeers := func(node *node) bool {
|
||||||
|
return node == nil
|
||||||
|
}
|
||||||
|
|
||||||
|
prunePeer := func(parent, node *node) {
|
||||||
|
if node.id != n.id && node.id == id {
|
||||||
|
delete(parent.peers, node.id)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
n.walk(untilNoMorePeers, prunePeer)
|
||||||
|
}
|
||||||
|
|
||||||
|
// PruneStalePeerNodes prunes the peers that have not been seen for longer than pruneTime
|
||||||
// It returns a map of the the nodes that got pruned
|
// It returns a map of the the nodes that got pruned
|
||||||
func (n *node) PruneStalePeers(pruneTime time.Duration) map[string]*node {
|
func (n *node) PruneStalePeers(pruneTime time.Duration) map[string]*node {
|
||||||
n.Lock()
|
n.Lock()
|
||||||
@ -252,6 +274,30 @@ func (n *node) PruneStalePeers(pruneTime time.Duration) map[string]*node {
|
|||||||
return pruned
|
return pruned
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// IncErrCount increments node error count
|
||||||
|
func (n *node) IncErrCount() {
|
||||||
|
n.Lock()
|
||||||
|
defer n.Unlock()
|
||||||
|
|
||||||
|
n.errCount++
|
||||||
|
}
|
||||||
|
|
||||||
|
// ResetErrCount reset node error count
|
||||||
|
func (n *node) ResetErrCount() {
|
||||||
|
n.Lock()
|
||||||
|
defer n.Unlock()
|
||||||
|
|
||||||
|
n.errCount = 0
|
||||||
|
}
|
||||||
|
|
||||||
|
// ErrCount returns node error count
|
||||||
|
func (n *node) ErrCount() int {
|
||||||
|
n.RLock()
|
||||||
|
defer n.RUnlock()
|
||||||
|
|
||||||
|
return n.errCount
|
||||||
|
}
|
||||||
|
|
||||||
// getTopology traverses node graph and builds node topology
|
// getTopology traverses node graph and builds node topology
|
||||||
// NOTE: this function is not thread safe
|
// NOTE: this function is not thread safe
|
||||||
func (n *node) getTopology(depth uint) *node {
|
func (n *node) getTopology(depth uint) *node {
|
||||||
|
@ -215,7 +215,22 @@ func TestDeletePeerNode(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestPruneStalePeerNodes(t *testing.T) {
|
func TestPrunePeer(t *testing.T) {
|
||||||
|
// complicated node graph
|
||||||
|
node := testSetup()
|
||||||
|
|
||||||
|
before := node.Nodes()
|
||||||
|
|
||||||
|
node.PrunePeer("peer3")
|
||||||
|
|
||||||
|
now := node.Nodes()
|
||||||
|
|
||||||
|
if len(now) != len(before)-1 {
|
||||||
|
t.Errorf("Expected pruned node count: %d, got: %d", len(before)-1, len(now))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestPruneStalePeers(t *testing.T) {
|
||||||
// complicated node graph
|
// complicated node graph
|
||||||
node := testSetup()
|
node := testSetup()
|
||||||
|
|
||||||
@ -224,7 +239,7 @@ func TestPruneStalePeerNodes(t *testing.T) {
|
|||||||
pruneTime := 10 * time.Millisecond
|
pruneTime := 10 * time.Millisecond
|
||||||
time.Sleep(pruneTime)
|
time.Sleep(pruneTime)
|
||||||
|
|
||||||
// should delete all nodes besides node
|
// should delete all nodes besides (root) node
|
||||||
pruned := node.PruneStalePeers(pruneTime)
|
pruned := node.PruneStalePeers(pruneTime)
|
||||||
|
|
||||||
if len(pruned) != len(nodes)-1 {
|
if len(pruned) != len(nodes)-1 {
|
||||||
|
Loading…
Reference in New Issue
Block a user