From 99a64bcf63fec02b0d5cc15bd792750ebf6db633 Mon Sep 17 00:00:00 2001 From: Matt Joiner Date: Thu, 2 Dec 2021 13:10:02 +1100 Subject: [PATCH] Wait between duplicate requests --- peerconn.go | 4 ++++ requesting.go | 17 ++++++++++++++++- torrent.go | 8 +++++--- 3 files changed, 25 insertions(+), 4 deletions(-) diff --git a/peerconn.go b/peerconn.go index fc3d9df3..7f8a78f1 100644 --- a/peerconn.go +++ b/peerconn.go @@ -620,6 +620,7 @@ func (cn *Peer) request(r RequestIndex) (more bool, err error) { } 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 @@ func (c *Peer) deleteRequest(r RequestIndex) bool { } 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 5e02b79b..6a611b94 100644 --- a/requesting.go +++ b/requesting.go @@ -119,6 +119,12 @@ func (p *peerRequests) Less(i, j int) bool { 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() @@ -177,6 +183,13 @@ func (p *Peer) getDesiredRequestState() (desired desiredRequestState) { 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 + } + } requestHeap.requestIndexes = append(requestHeap.requestIndexes, r) }) }, @@ -276,10 +289,12 @@ func (p *Peer) applyRequestState(next desiredRequestState) bool { 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 c4ecf07f..30ccbb08 100644 --- a/torrent.go +++ b/torrent.go @@ -139,6 +139,7 @@ type Torrent struct { // 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 @@ func (t *Torrent) onSetInfo() { 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) maybeNewConns() { 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 }