github.com/sixexorg/magnetic-ring@v0.0.0-20191119090307-31705a21e419/p2pserver/spcnode/nodes.go (about) 1 package spcnode 2 3 import ( 4 "sync" 5 "time" 6 7 msgpack "github.com/sixexorg/magnetic-ring/p2pserver/message" 8 ) 9 10 type NodeStar struct { 11 sync.RWMutex 12 quit chan bool 13 p2pser SpectNodeP2PSer 14 connANodes map[uint64]*NodeInfo // 保存对端A节点的信息 15 bStarNode bool 16 } 17 18 func NewNodeStar(p2pser SpectNodeP2PSer) *NodeStar { 19 ser := new(NodeStar) 20 ser.quit = make(chan bool) 21 ser.p2pser = p2pser 22 ser.connANodes = make(map[uint64]*NodeInfo) 23 24 return ser 25 } 26 27 func (this *NodeStar) BStarNode() bool { 28 return this.bStarNode 29 } 30 31 func (this *NodeStar) OnReceive(peerid uint64,bothersidereq bool) { 32 //fmt.Println(" ******** NodeStar OnReceive......peerid:",peerid,",bothersidereq:",bothersidereq) 33 this.RLock() 34 defer this.RUnlock() 35 36 if bothersidereq { 37 if _,ok := this.connANodes[peerid]; ok { 38 this.connANodes[peerid] = &NodeInfo{ 39 reqtime: time.Now().Unix(), 40 errcount: 0, 41 } 42 } 43 } else { 44 delete(this.connANodes,peerid) 45 } 46 } 47 48 func (this *NodeStar) Close() { 49 this.quit <- true 50 } 51 52 func (this *NodeStar) Start() { 53 go this.heartBeatService() 54 } 55 56 func (this *NodeStar) heartBeatService() { 57 t := time.NewTicker(time.Second * PingSpcInterval) 58 defer t.Stop() 59 60 for { 61 select { 62 case <- t.C: 63 this.pingANode() 64 this.timeout() 65 case <-this.quit: 66 break 67 } 68 } 69 } 70 71 func (this *NodeStar) timeout() { 72 this.RLock() 73 defer this.RUnlock() 74 75 errpeerid := make([]uint64,0) 76 for peerid,nodeinfo := range this.connANodes { 77 if time.Now().Unix() - nodeinfo.reqtime >= PingSpcTimeOut { 78 nodeinfo.errcount++ 79 } 80 81 if nodeinfo.errcount >= PingSpcTimeOutCount { 82 errpeerid = append(errpeerid,peerid) 83 } 84 } 85 for _,id := range errpeerid { 86 delete(this.connANodes,id) 87 } 88 } 89 90 func (this *NodeStar) pingANode() { 91 this.RLock() 92 defer this.RUnlock() 93 94 peernul := make([]uint64,0) 95 for peerid,info := range this.connANodes { 96 bnul := this.send(peerid) 97 if bnul { 98 peernul = append(peernul,peerid) 99 } else { 100 this.connANodes[peerid] = &NodeInfo{ 101 reqtime: time.Now().Unix(), 102 errcount: 0, 103 nodeID: info.nodeID, 104 } 105 } 106 } 107 for _,id := range peernul { 108 delete(this.connANodes,id) 109 } 110 } 111 112 func (this *NodeStar) send(peerid uint64) bool { 113 peer := this.p2pser.GetNode(peerid) 114 if peer == nil { 115 return true 116 } 117 pingspc := msgpack.NewPingSpcMsg(false) 118 go this.p2pser.Send(peer, pingspc, false) 119 return false 120 } 121 122 func (this *NodeStar) AddStar() { 123 this.bStarNode = true 124 } 125 126 func (this *NodeStar) DelStar() { 127 this.bStarNode = false 128 this.delAllPeers() 129 } 130 131 func (this *NodeStar) GetPeers() []uint64 { 132 this.RLock() 133 defer this.RUnlock() 134 135 peers := make([]uint64,0) 136 for peerid,_ := range this.connANodes { 137 peers = append(peers,peerid) 138 } 139 return peers 140 } 141 142 func (this *NodeStar) AddPeers(id uint64) { 143 this.RLock() 144 defer this.RUnlock() 145 146 this.connANodes[id] = &NodeInfo{ 147 reqtime: time.Now().Unix(), 148 errcount: 0, 149 } 150 } 151 152 // Delete the org connected by the A node 153 // func (this *NodeA) DelPeers(ids []uint64) { 154 // this.RLock() 155 // defer this.RUnlock() 156 157 // for _,id := range ids { 158 // delete(this.connStellarNodes,id) 159 // } 160 // } 161 162 func (this *NodeStar) delAllPeers() { 163 this.connANodes = make(map[uint64]*NodeInfo) 164 }