github.com/anacrolix/torrent@v1.61.0/conn-stats.go (about) 1 package torrent 2 3 import ( 4 "io" 5 6 pp "github.com/anacrolix/torrent/peer_protocol" 7 ) 8 9 // Various connection-level metrics. At the Torrent level these are aggregates. Chunks are messages 10 // with data payloads. Data is actual torrent content without any overhead. Useful is something we 11 // needed locally. Intended is something we were expecting (I think such as when we cancel a request 12 // but it arrives anyway). Written is things sent to the peer, and Read is stuff received from them. 13 // Due to the implementation of Count, must be aligned on some platforms: See 14 // https://github.com/anacrolix/torrent/issues/262. 15 type ConnStats struct { 16 // Total bytes on the wire. Includes handshakes and encryption. 17 BytesWritten Count 18 BytesWrittenData Count 19 20 BytesRead Count 21 BytesReadData Count 22 BytesReadUsefulData Count 23 BytesReadUsefulIntendedData Count 24 25 ChunksWritten Count 26 27 ChunksRead Count 28 ChunksReadUseful Count 29 ChunksReadWasted Count 30 31 MetadataChunksRead Count 32 33 // Number of pieces data was written to, that subsequently passed verification. 34 PiecesDirtiedGood Count 35 // Number of pieces data was written to, that subsequently failed verification. Note that a 36 // connection may not have been the sole dirtier of a piece. 37 PiecesDirtiedBad Count 38 } 39 40 func (me *ConnStats) Copy() (ret ConnStats) { 41 return copyCountFields(me) 42 } 43 44 func (cs *ConnStats) wroteMsg(msg *pp.Message) { 45 // TODO: Track messages and not just chunks. 46 switch msg.Type { 47 case pp.Piece: 48 cs.ChunksWritten.Add(1) 49 cs.BytesWrittenData.Add(int64(len(msg.Piece))) 50 } 51 } 52 53 func (cs *ConnStats) receivedChunk(size int64) { 54 cs.ChunksRead.Add(1) 55 cs.BytesReadData.Add(size) 56 } 57 58 func (cs *ConnStats) incrementPiecesDirtiedGood() bool { 59 cs.PiecesDirtiedGood.Add(1) 60 // This method is used as an iterator and should never return early. 61 return true 62 } 63 64 func (cs *ConnStats) incrementPiecesDirtiedBad() bool { 65 cs.PiecesDirtiedBad.Add(1) 66 // This method is used as an iterator and should never return early. 67 return true 68 } 69 70 func add(n int64, f func(*ConnStats) *Count) func(*ConnStats) { 71 return func(cs *ConnStats) { 72 p := f(cs) 73 p.Add(n) 74 } 75 } 76 77 type connStatsReadWriter struct { 78 rw io.ReadWriter 79 c *PeerConn 80 } 81 82 func (me connStatsReadWriter) Write(b []byte) (n int, err error) { 83 n, err = me.rw.Write(b) 84 me.c.wroteBytes(int64(n)) 85 return 86 } 87 88 func (me connStatsReadWriter) Read(b []byte) (n int, err error) { 89 n, err = me.rw.Read(b) 90 me.c.readBytes(int64(n)) 91 return 92 }