You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

183 lines
3.9 KiB

10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
  1. package peer
  2. import (
  3. "errors"
  4. "sync"
  5. "sync/atomic"
  6. . "github.com/tendermint/tendermint/binary"
  7. . "github.com/tendermint/tendermint/common"
  8. "github.com/tendermint/tendermint/merkle"
  9. )
  10. /* Client
  11. A client is half of a p2p system.
  12. It can reach out to the network and establish connections with servers.
  13. A client doesn't listen for incoming connections -- that's done by the server.
  14. makePeerFn is a factory method for generating new peers from new *Connections.
  15. makePeerFn(nil) must return a prototypical peer that represents the self "peer".
  16. XXX what about peer disconnects?
  17. */
  18. type Client struct {
  19. addrBook *AddrBook
  20. targetNumPeers int
  21. makePeerFn func(*Connection) *Peer
  22. self *Peer
  23. recvQueues map[String]chan *InboundPacket
  24. mtx sync.Mutex
  25. peers merkle.Tree // addr -> *Peer
  26. quit chan struct{}
  27. stopped uint32
  28. }
  29. var (
  30. CLIENT_STOPPED_ERROR = errors.New("Client already stopped")
  31. CLIENT_DUPLICATE_PEER_ERROR = errors.New("Duplicate peer")
  32. )
  33. func NewClient(makePeerFn func(*Connection) *Peer) *Client {
  34. self := makePeerFn(nil)
  35. if self == nil {
  36. Panicf("makePeerFn(nil) must return a prototypical peer for self")
  37. }
  38. recvQueues := make(map[String]chan *InboundPacket)
  39. for chName, _ := range self.channels {
  40. recvQueues[chName] = make(chan *InboundPacket)
  41. }
  42. c := &Client{
  43. addrBook: nil, // TODO
  44. targetNumPeers: 0, // TODO
  45. makePeerFn: makePeerFn,
  46. self: self,
  47. recvQueues: recvQueues,
  48. peers: merkle.NewIAVLTree(nil),
  49. quit: make(chan struct{}),
  50. stopped: 0,
  51. }
  52. return c
  53. }
  54. func (c *Client) Stop() {
  55. log.Infof("Stopping client")
  56. // lock
  57. c.mtx.Lock()
  58. if atomic.CompareAndSwapUint32(&c.stopped, 0, 1) {
  59. close(c.quit)
  60. // stop each peer.
  61. for peerValue := range c.peers.Values() {
  62. peer := peerValue.(*Peer)
  63. peer.Stop()
  64. }
  65. // empty tree.
  66. c.peers = merkle.NewIAVLTree(nil)
  67. }
  68. c.mtx.Unlock()
  69. // unlock
  70. }
  71. func (c *Client) AddPeerWithConnection(conn *Connection, outgoing bool) (*Peer, error) {
  72. if atomic.LoadUint32(&c.stopped) == 1 {
  73. return nil, CLIENT_STOPPED_ERROR
  74. }
  75. log.Infof("Adding peer with connection: %v, outgoing: %v", conn, outgoing)
  76. peer := c.makePeerFn(conn)
  77. peer.outgoing = outgoing
  78. err := c.addPeer(peer)
  79. if err != nil {
  80. return nil, err
  81. }
  82. go peer.Start(c.recvQueues)
  83. return peer, nil
  84. }
  85. func (c *Client) Broadcast(pkt Packet) (numSuccess, numFailure int) {
  86. if atomic.LoadUint32(&c.stopped) == 1 {
  87. return
  88. }
  89. log.Tracef("Broadcast on [%v] len: %v", pkt.Channel, len(pkt.Bytes))
  90. for v := range c.peers.Values() {
  91. peer := v.(*Peer)
  92. success := peer.TrySend(pkt)
  93. log.Tracef("Broadcast for peer %v success: %v", peer, success)
  94. if success {
  95. numSuccess += 1
  96. } else {
  97. numFailure += 1
  98. }
  99. }
  100. return
  101. }
  102. // blocks until a message is popped.
  103. func (c *Client) Receive(chName String) *InboundPacket {
  104. if atomic.LoadUint32(&c.stopped) == 1 {
  105. return nil
  106. }
  107. log.Tracef("Receive on [%v]", chName)
  108. q := c.recvQueues[chName]
  109. if q == nil {
  110. Panicf("Expected recvQueues[%f], found none", chName)
  111. }
  112. select {
  113. case <-c.quit:
  114. return nil
  115. case inPacket := <-q:
  116. return inPacket
  117. }
  118. }
  119. func (c *Client) Peers() merkle.Tree {
  120. // lock & defer
  121. c.mtx.Lock()
  122. defer c.mtx.Unlock()
  123. return c.peers.Copy()
  124. // unlock deferred
  125. }
  126. func (c *Client) StopPeer(peer *Peer) {
  127. // lock
  128. c.mtx.Lock()
  129. peerValue, _ := c.peers.Remove(peer.RemoteAddress())
  130. c.mtx.Unlock()
  131. // unlock
  132. peer_ := peerValue.(*Peer)
  133. if peer_ != nil {
  134. peer_.Stop()
  135. }
  136. }
  137. func (c *Client) addPeer(peer *Peer) error {
  138. addr := peer.RemoteAddress()
  139. // lock & defer
  140. c.mtx.Lock()
  141. defer c.mtx.Unlock()
  142. if c.stopped == 1 {
  143. return CLIENT_STOPPED_ERROR
  144. }
  145. if !c.peers.Has(addr) {
  146. log.Tracef("Actually putting addr: %v, peer: %v", addr, peer)
  147. c.peers.Put(addr, peer)
  148. return nil
  149. } else {
  150. // ignore duplicate peer for addr.
  151. log.Infof("Ignoring duplicate peer for addr %v", addr)
  152. return CLIENT_DUPLICATE_PEER_ERROR
  153. }
  154. // unlock deferred
  155. }