// Various connection-level metrics. At the Torrent level these are aggregates. Chunks are messages
// with data payloads. Data is actual torrent content without any overhead. Useful is something we
-// needed locally. Unwanted is something we didn't ask for (but may still be useful). Written is
-// things sent to the peer, and Read is stuff received from them. Due to the implementation of
-// Count, must be aligned on some platforms: See https://github.com/anacrolix/torrent/issues/262.
+// needed locally. Intended is something we were expecting (I think such as when we cancel a request
+// but it arrives anyway). Written is things sent to the peer, and Read is stuff received from them.
+// Due to the implementation of Count, must be aligned on some platforms: See
+// https://github.com/anacrolix/torrent/issues/262.
type ConnStats struct {
// Total bytes on the wire. Includes handshakes and encryption.
BytesWritten Count
import (
"github.com/RoaringBitmap/roaring"
+ pp "github.com/anacrolix/torrent/peer_protocol"
"github.com/anacrolix/torrent/metainfo"
)
type newHotPeerImpl interface {
lastWriteUploadRate() float64
// Bookkeeping for a chunk being received and any specific checks.
- checkReceivedChunk(ri RequestIndex) error
+ checkReceivedChunk(ri RequestIndex, msg *pp.Message, req Request) (intended bool, err error)
// Whether we're expecting to receive chunks because we have outstanding requests. Used for
// example to calculate download rate.
expectingChunks() bool
ChunksReceived.Add("while choked", 1)
}
- err = c.peerImpl.checkReceivedChunk(req)
+ intended, err := c.peerImpl.checkReceivedChunk(req, msg, ppReq)
if err != nil {
return err
}
- if c.peerChoking && c.peerAllowedFast.Contains(pieceIndex(ppReq.Index)) {
- ChunksReceived.Add("due to allowed fast", 1)
- }
-
- // The request needs to be deleted immediately to prevent cancels occurring asynchronously when
- // have actually already received the piece, while we have the Client unlocked to write the data
- // out.
- intended := false
- {
- if c.requestState.Requests.Contains(req) {
- for _, f := range c.callbacks.ReceivedRequested {
- f(PeerMessageEvent{c, msg})
- }
- }
- // Request has been satisfied.
- if c.deleteRequest(req) || c.requestState.Cancelled.CheckedRemove(req) {
- intended = true
- if c.isLowOnRequests() {
- c.onNeedUpdateRequests("Peer.receiveChunk deleted request")
- }
- } else {
- ChunksReceived.Add("unintended", 1)
- }
- }
-
cl := t.cl
// Do we actually want this chunk?
me.protocolLogger = me.logger.WithNames(protocolLoggingName)
}
-func (c *PeerConn) checkReceivedChunk(req RequestIndex) error {
+func (c *PeerConn) checkReceivedChunk(req RequestIndex, msg *pp.Message, ppReq Request) (intended bool, err error) {
if c.validReceiveChunks[req] <= 0 {
ChunksReceived.Add("unexpected", 1)
- return errors.New("received unexpected chunk")
+ err = errors.New("received unexpected chunk")
+ return
}
c.decExpectedChunkReceive(req)
- return nil
+
+ if c.peerChoking && c.peerAllowedFast.Contains(pieceIndex(ppReq.Index)) {
+ ChunksReceived.Add("due to allowed fast", 1)
+ }
+ // The request needs to be deleted immediately to prevent cancels occurring asynchronously when
+ // have actually already received the piece, while we have the Client unlocked to write the data
+ // out.
+ {
+ if c.requestState.Requests.Contains(req) {
+ for _, f := range c.callbacks.ReceivedRequested {
+ f(PeerMessageEvent{c.peerPtr(), msg})
+ }
+ }
+ // Request has been satisfied.
+ if c.deleteRequest(req) || c.requestState.Cancelled.CheckedRemove(req) {
+ intended = true
+ if c.isLowOnRequests() {
+ c.onNeedUpdateRequests("Peer.receiveChunk deleted request")
+ }
+ } else {
+ ChunksReceived.Add("unintended", 1)
+ }
+ }
+
+ return
}
return len(me.activeRequests) > 0
}
-func (me *webseedPeer) checkReceivedChunk(ri RequestIndex) error {
- return nil
+func (me *webseedPeer) checkReceivedChunk(RequestIndex, *pp.Message, Request) (bool, error) {
+ return true, nil
}
func (me *webseedPeer) numRequests() int {
"begin", begin,
"end", end,
"len", end-begin,
- "avail", ws.peer.requestState.Requests.GetCardinality())
+ )
go ws.runRequest(&wsReq)
}