From 1201ccc53bd04118b361c20a7ece4d597aedb4bc Mon Sep 17 00:00:00 2001 From: Matt Joiner Date: Mon, 18 Oct 2021 18:40:33 +1100 Subject: [PATCH] Refresh requests after a second of no updates --- client.go | 11 +++++++++++ peerconn.go | 4 ++++ requesting.go | 12 +++++++++--- 3 files changed, 24 insertions(+), 3 deletions(-) diff --git a/client.go b/client.go index 3afe64a2..af18b6d0 100644 --- a/client.go +++ b/client.go @@ -9,6 +9,7 @@ import ( "expvar" "fmt" "io" + "math" "net" "net/http" "sort" @@ -956,6 +957,16 @@ func (cl *Client) runHandshookConn(c *PeerConn, t *Torrent) error { defer t.dropConnection(c) c.startWriter() cl.sendInitialMessages(c, t) + c.updateRequestsTimer = time.AfterFunc(math.MaxInt64, func() { + if c.needRequestUpdate != "" { + return + } + if c.actualRequestState.Requests.IsEmpty() { + panic("updateRequestsTimer should have been stopped") + } + c.updateRequests("updateRequestsTimer") + }) + c.updateRequestsTimer.Stop() err := c.mainReadLoop() if err != nil { return fmt.Errorf("main read loop: %w", err) diff --git a/peerconn.go b/peerconn.go index eebfc029..545e29f1 100644 --- a/peerconn.go +++ b/peerconn.go @@ -84,6 +84,7 @@ type Peer struct { // Stuff controlled by the local peer. needRequestUpdate string actualRequestState requestState + updateRequestsTimer *time.Timer cancelledRequests roaring.Bitmap lastBecameInterested time.Time priorInterest time.Duration @@ -414,6 +415,9 @@ func (cn *PeerConn) onClose() { if cn.pex.IsEnabled() { cn.pex.Close() } + if cn.updateRequestsTimer != nil { + cn.updateRequestsTimer.Stop() + } cn.tickleWriter() if cn.conn != nil { cn.conn.Close() diff --git a/requesting.go b/requesting.go index 1da22900..7d0c8f2f 100644 --- a/requesting.go +++ b/requesting.go @@ -253,7 +253,7 @@ func (p *Peer) applyNextRequestState() bool { } func (p *Peer) applyRequestState(next requestState) bool { - current := p.actualRequestState + current := &p.actualRequestState if !p.setInterested(next.Interested) { return false } @@ -268,8 +268,9 @@ func (p *Peer) applyRequestState(next requestState) bool { } next.Requests.Iterate(func(req uint32) bool { if p.cancelledRequests.Contains(req) { - log.Printf("waiting for cancelled request %v", req) - return false + // Waiting for a reject or piece message, which will suitably trigger us to update our + // requests, so we can skip this one with no additional consideration. + return true } if maxRequests(current.Requests.GetCardinality()) >= p.nominalMaxRequests() { log.Printf("not assigning all requests [desired=%v, cancelled=%v, max=%v]", @@ -288,6 +289,11 @@ func (p *Peer) applyRequestState(next requestState) bool { }) if more { p.needRequestUpdate = "" + if current.Requests.IsEmpty() { + p.updateRequestsTimer.Stop() + } else { + p.updateRequestsTimer.Reset(time.Second) + } } return more } -- 2.48.1