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.

159 lines
4.0 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
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. . "github.com/tendermint/tendermint/common"
  4. . "github.com/tendermint/tendermint/binary"
  5. "github.com/tendermint/tendermint/merkle"
  6. "sync/atomic"
  7. "sync"
  8. "errors"
  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. peerMaker is a factory method for generating new peers from new *Connections.
  15. peerMaker(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. peerMaker func(*Connection) *Peer
  22. self *Peer
  23. inQueues map[String]chan *InboundMsg
  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(peerMaker func(*Connection) *Peer) *Client {
  34. self := peerMaker(nil)
  35. if self == nil {
  36. Panicf("peerMaker(nil) must return a prototypical peer for self")
  37. }
  38. inQueues := make(map[String]chan *InboundMsg)
  39. for chName, _ := range self.channels {
  40. inQueues[chName] = make(chan *InboundMsg)
  41. }
  42. c := &Client{
  43. addrBook: nil, // TODO
  44. targetNumPeers: 0, // TODO
  45. peerMaker: peerMaker,
  46. self: self,
  47. inQueues: inQueues,
  48. peers: merkle.NewIAVLTree(nil),
  49. quit: make(chan struct{}),
  50. stopped: 0,
  51. }
  52. return c
  53. }
  54. func (c *Client) Stop() {
  55. // lock
  56. c.mtx.Lock()
  57. if atomic.CompareAndSwapUint32(&c.stopped, 0, 1) {
  58. close(c.quit)
  59. // stop each peer.
  60. for peerValue := range c.peers.Values() {
  61. peer := peerValue.(*Peer)
  62. peer.Stop()
  63. }
  64. // empty tree.
  65. c.peers = merkle.NewIAVLTree(nil)
  66. }
  67. c.mtx.Unlock()
  68. // unlock
  69. }
  70. func (c *Client) AddPeerWithConnection(conn *Connection, outgoing bool) (*Peer, error) {
  71. if atomic.LoadUint32(&c.stopped) == 1 { return nil, CLIENT_STOPPED_ERROR }
  72. peer := c.peerMaker(conn)
  73. peer.outgoing = outgoing
  74. err := c.addPeer(peer)
  75. if err != nil { return nil, err }
  76. go peer.Start(c.inQueues)
  77. return peer, nil
  78. }
  79. func (c *Client) Broadcast(chName String, msg Msg) {
  80. if atomic.LoadUint32(&c.stopped) == 1 { return }
  81. for v := range c.peersCopy().Values() {
  82. peer := v.(*Peer)
  83. success := peer.TryQueueOut(chName , msg)
  84. if !success {
  85. // TODO: notify the peer
  86. }
  87. }
  88. }
  89. func (c *Client) PopMessage(chName String) *InboundMsg {
  90. if atomic.LoadUint32(&c.stopped) == 1 { return nil }
  91. q := c.inQueues[chName]
  92. if q == nil { Panicf("Expected inQueues[%f], found none", chName) }
  93. for {
  94. select {
  95. case <-c.quit:
  96. return nil
  97. case inMsg := <-q:
  98. return inMsg
  99. }
  100. }
  101. }
  102. func (c *Client) StopPeer(peer *Peer) {
  103. // lock
  104. c.mtx.Lock()
  105. peerValue, _ := c.peers.Remove(peer.RemoteAddress())
  106. c.mtx.Unlock()
  107. // unlock
  108. peer_ := peerValue.(*Peer)
  109. if peer_ != nil {
  110. peer_.Stop()
  111. }
  112. }
  113. func (c *Client) addPeer(peer *Peer) error {
  114. addr := peer.RemoteAddress()
  115. // lock & defer
  116. c.mtx.Lock(); defer c.mtx.Unlock()
  117. if c.stopped == 1 { return CLIENT_STOPPED_ERROR }
  118. if !c.peers.Has(addr) {
  119. c.peers.Put(addr, peer)
  120. return nil
  121. } else {
  122. // ignore duplicate peer for addr.
  123. log.Infof("Ignoring duplicate peer for addr %v", addr)
  124. return CLIENT_DUPLICATE_PEER_ERROR
  125. }
  126. // unlock deferred
  127. }
  128. func (c *Client) peersCopy() merkle.Tree {
  129. // lock & defer
  130. c.mtx.Lock(); defer c.mtx.Unlock()
  131. return c.peers.Copy()
  132. // unlock deferred
  133. }