peerconn.go | 4 ++++ requesting.go | 17 ++++++++++++++++- torrent.go | 8 +++++--- diff --git a/peerconn.go b/peerconn.go index fc3d9df3cb6132d8f36900f2e2b472e64c5144e1..7f8a78f13afc1b5d3a356c14d7ca2002dcccb83c 100644 --- a/peerconn.go +++ b/peerconn.go @@ -620,6 +620,7 @@ cn.validReceiveChunks = make(map[RequestIndex]int) } cn.validReceiveChunks[r]++ cn.t.pendingRequests.Inc(r) + cn.t.lastRequested[r] = time.Now() cn.updateExpectingChunks() ppReq := cn.t.requestIndexToRequest(r) for _, f := range cn.callbacks.SentRequest { @@ -1550,6 +1551,9 @@ f(PeerRequestEvent{c, c.t.requestIndexToRequest(r)}) } c.updateExpectingChunks() c.t.pendingRequests.Dec(r) + if c.t.pendingRequests.Get(r) == 0 { + delete(c.t.lastRequested, r) + } return true } diff --git a/requesting.go b/requesting.go index 5e02b79ba74f736bae5f3e006763f66c83551071..6a611b94730b86c7ac207482d8e0843c88fd2e33 100644 --- a/requesting.go +++ b/requesting.go @@ -119,6 +119,12 @@ ) ml = ml.Int( int(leftPiece.availability), int(rightPiece.availability)) + leftLastRequested := p.peer.t.lastRequested[leftRequest] + rightLastRequested := p.peer.t.lastRequested[rightRequest] + ml = ml.EagerSameLess( + leftLastRequested.Equal(rightLastRequested), + leftLastRequested.Before(rightLastRequested), + ) ml = ml.Uint32(leftPieceIndex, rightPieceIndex) ml = ml.Uint32(leftRequest, rightRequest) return ml.MustLess() @@ -174,6 +180,13 @@ // the peer respond yet (and the request was retained because we are using the // fast extension). if p.peerChoking && !p.actualRequestState.Requests.Contains(r) { // We can't request this right now. + return + } + } + // Note that we can still be interested if we filter all requests due to being + // recently requested from another peer. + if !p.actualRequestState.Requests.Contains(r) { + if time.Since(p.t.lastRequested[r]) < time.Second { return } } @@ -276,10 +289,12 @@ if !more { break } } + // TODO: This may need to change, we might want to update even if there were no requests due to + // filtering them for being recently requested already. p.updateRequestsTimer.Stop() if more { p.needRequestUpdate = "" - if !current.Requests.IsEmpty() { + if current.Interested { p.updateRequestsTimer.Reset(3 * time.Second) } } diff --git a/torrent.go b/torrent.go index c4ecf07f4cfb98e69af861b28c3eb6bad23a1f1c..30ccbb08a001cd52c84088b599a2451c26168899 100644 --- a/torrent.go +++ b/torrent.go @@ -139,6 +139,7 @@ initialPieceCheckDisabled bool // Count of each request across active connections. pendingRequests pendingRequests + lastRequested map[RequestIndex]time.Time // Chunks we've written to since the corresponding piece was last checked. dirtyChunks roaring.Bitmap @@ -463,6 +464,7 @@ t.cl.event.Broadcast() close(t.gotMetainfoC) t.updateWantPeersEvent() t.pendingRequests.Init(t.numRequests()) + t.lastRequested = make(map[RequestIndex]time.Time) t.tryCreateMorePieceHashers() t.iterPeers(func(p *Peer) { p.onGotInfo(t.info) @@ -1110,9 +1112,9 @@ func (t *Torrent) piecePriorityChanged(piece pieceIndex, reason string) { if t._pendingPieces.Contains(uint32(piece)) { t.iterPeers(func(c *Peer) { - if c.actualRequestState.Interested { - return - } + // if c.actualRequestState.Interested { + // return + // } if !c.isLowOnRequests() { return }