github.com/uber/kraken@v0.1.4/lib/torrent/scheduler/dispatch/peer.go (about) 1 // Copyright (c) 2016-2019 Uber Technologies, Inc. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 package dispatch 15 16 import ( 17 "sync" 18 "time" 19 20 "github.com/uber/kraken/core" 21 "github.com/andres-erbsen/clock" 22 "github.com/willf/bitset" 23 ) 24 25 // peer consolidates bookeeping for a remote peer. 26 type peer struct { 27 id core.PeerID 28 29 // Tracks the pieces which the remote peer has. 30 bitfield *syncBitfield 31 32 messages Messages 33 34 clk clock.Clock 35 36 // May be accessed outside of the peer struct. 37 pstats *peerStats 38 39 mu sync.Mutex // Protects the following fields: 40 lastGoodPieceReceived time.Time 41 lastPieceSent time.Time 42 } 43 44 func newPeer( 45 peerID core.PeerID, 46 b *bitset.BitSet, 47 messages Messages, 48 clk clock.Clock, 49 pstats *peerStats) *peer { 50 51 return &peer{ 52 id: peerID, 53 bitfield: newSyncBitfield(b), 54 messages: messages, 55 clk: clk, 56 pstats: pstats, 57 } 58 } 59 60 func (p *peer) String() string { 61 return p.id.String() 62 } 63 64 func (p *peer) getLastGoodPieceReceived() time.Time { 65 p.mu.Lock() 66 defer p.mu.Unlock() 67 68 return p.lastGoodPieceReceived 69 } 70 71 func (p *peer) touchLastGoodPieceReceived() { 72 p.mu.Lock() 73 defer p.mu.Unlock() 74 75 p.lastGoodPieceReceived = p.clk.Now() 76 } 77 78 func (p *peer) getLastPieceSent() time.Time { 79 p.mu.Lock() 80 defer p.mu.Unlock() 81 82 return p.lastPieceSent 83 } 84 85 func (p *peer) touchLastPieceSent() { 86 p.mu.Lock() 87 defer p.mu.Unlock() 88 89 p.lastPieceSent = p.clk.Now() 90 } 91 92 // peerStats wraps stats collected for a given peer. 93 type peerStats struct { 94 mu sync.Mutex 95 pieceRequestsSent int // Pieces we requested from the peer. 96 pieceRequestsReceived int // Pieces the peer requested from us. 97 piecesSent int // Pieces we sent to the peer. 98 99 // Pieces we received from the peer that we didn't already have. 100 goodPiecesReceived int 101 // Pieces we received from the peer that we already had. 102 duplicatePiecesReceived int 103 } 104 105 func (s *peerStats) getPieceRequestsSent() int { 106 s.mu.Lock() 107 defer s.mu.Unlock() 108 109 return s.pieceRequestsSent 110 } 111 112 func (s *peerStats) incrementPieceRequestsSent() { 113 s.mu.Lock() 114 defer s.mu.Unlock() 115 116 s.pieceRequestsSent++ 117 } 118 119 func (s *peerStats) getPieceRequestsReceived() int { 120 s.mu.Lock() 121 defer s.mu.Unlock() 122 123 return s.pieceRequestsReceived 124 } 125 126 func (s *peerStats) incrementPieceRequestsReceived() { 127 s.mu.Lock() 128 defer s.mu.Unlock() 129 130 s.pieceRequestsReceived++ 131 } 132 133 func (s *peerStats) getPiecesSent() int { 134 s.mu.Lock() 135 defer s.mu.Unlock() 136 137 return s.piecesSent 138 } 139 140 func (s *peerStats) incrementPiecesSent() { 141 s.mu.Lock() 142 defer s.mu.Unlock() 143 144 s.piecesSent++ 145 } 146 147 func (s *peerStats) getGoodPiecesReceived() int { 148 s.mu.Lock() 149 defer s.mu.Unlock() 150 151 return s.goodPiecesReceived 152 } 153 154 func (s *peerStats) incrementGoodPiecesReceived() { 155 s.mu.Lock() 156 defer s.mu.Unlock() 157 158 s.goodPiecesReceived++ 159 } 160 161 func (s *peerStats) getDuplicatePiecesReceived() int { 162 s.mu.Lock() 163 defer s.mu.Unlock() 164 165 return s.duplicatePiecesReceived 166 } 167 168 func (s *peerStats) incrementDuplicatePiecesReceived() { 169 s.mu.Lock() 170 defer s.mu.Unlock() 171 172 s.duplicatePiecesReceived++ 173 }