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  }