]> Sergey Matveev's repositories - btrtrc.git/commitdiff
Add low requests check
authorMatt Joiner <anacrolix@gmail.com>
Wed, 20 Oct 2021 23:48:43 +0000 (10:48 +1100)
committerMatt Joiner <anacrolix@gmail.com>
Wed, 20 Oct 2021 23:48:43 +0000 (10:48 +1100)
This is an optimization for webseeds, which have 10 synchronous request routines, and if the request count dips below 10, some sit idle. There is probably something similar to be done with PeerConns, which won't update until there are zero requests, but there there is a timer to refresh updates, and the queues are very long (typically 512-2048).

client.go
peer-impl.go
peerconn.go
torrent.go
webseed-peer.go

index 72013b99bf13ecbe34f400341ce41033114021b8..142213c08934cfc66c70d07df57b37777f060709 100644 (file)
--- a/client.go
+++ b/client.go
@@ -983,7 +983,7 @@ func (c *Peer) updateRequestsTimerFunc() {
        if c.needRequestUpdate != "" {
                return
        }
-       if c.actualRequestState.Requests.IsEmpty() {
+       if c.isLowOnRequests() {
                // If there are no outstanding requests, then a request update should have already run.
                return
        }
index 4dbc6b4c08046832804203eb80a638d944e28619..b5cf028ecd98b3a75d7d927b31c165b735ade44f 100644 (file)
@@ -10,6 +10,8 @@ import (
 type peerImpl interface {
        // Trigger the actual request state to get updated
        handleUpdateRequests()
+       // Whether the outstanding local request cardinality is low enough to warrant an update.
+       isLowOnRequests() bool
        writeInterested(interested bool) bool
 
        // Neither of these return buffer room anymore, because they're currently both posted. There's
index a9d0baad2696e0fc5e0161b2a9dc723bc162dcea..005c6b7d93f1c497b703f0a514f61861fd7a64cb 100644 (file)
@@ -630,7 +630,7 @@ func (me *PeerConn) _cancel(r RequestIndex) bool {
                if !me.deleteRequest(r) {
                        panic("request not existing should have been guarded")
                }
-               if me.actualRequestState.Requests.IsEmpty() {
+               if me.isLowOnRequests() {
                        me.updateRequests("Peer.cancel")
                }
        }
@@ -1195,7 +1195,7 @@ func (c *PeerConn) mainReadLoop() (err error) {
 
 func (c *Peer) remoteRejectedRequest(r RequestIndex) {
        if c.deleteRequest(r) {
-               if c.actualRequestState.Requests.IsEmpty() {
+               if c.isLowOnRequests() {
                        c.updateRequests("Peer.remoteRejectedRequest")
                }
                c.decExpectedChunkReceive(r)
@@ -1334,7 +1334,7 @@ func (c *Peer) receiveChunk(msg *pp.Message) error {
                        if !c.peerChoking {
                                c._chunksReceivedWhileExpecting++
                        }
-                       if c.actualRequestState.Requests.IsEmpty() {
+                       if c.isLowOnRequests() {
                                c.updateRequests("Peer.receiveChunk deleted request")
                        }
                } else {
@@ -1542,9 +1542,6 @@ func (c *Peer) deleteAllRequests() {
        if !c.actualRequestState.Requests.IsEmpty() {
                panic(c.actualRequestState.Requests.GetCardinality())
        }
-       // for c := range c.t.conns {
-       //      c.tickleWriter()
-       // }
 }
 
 // This is called when something has changed that should wake the writer, such as putting stuff into
@@ -1671,3 +1668,7 @@ func (p *Peer) TryAsPeerConn() (*PeerConn, bool) {
        pc, ok := p.peerImpl.(*PeerConn)
        return pc, ok
 }
+
+func (pc *PeerConn) isLowOnRequests() bool {
+       return pc.actualRequestState.Requests.IsEmpty()
+}
index 9227734271db72514e0aa9b592dc2bd6b0460ee2..f594c9f625c255a1a22b1d77b6b5db030ccdb7e6 100644 (file)
@@ -1085,7 +1085,7 @@ func (t *Torrent) piecePriorityChanged(piece pieceIndex, reason string) {
                        if c.actualRequestState.Interested {
                                return
                        }
-                       if !c.actualRequestState.Requests.IsEmpty() {
+                       if !c.isLowOnRequests() {
                                return
                        }
                        if !c.peerHasPiece(piece) {
@@ -2225,6 +2225,7 @@ func (t *Torrent) addWebSeed(url string) {
                        Url:        url,
                },
                activeRequests: make(map[Request]webseed.Request, maxRequests),
+               maxRequests:    maxRequests,
        }
        ws.peer.initUpdateRequestsTimer()
        ws.requesterCond.L = t.cl.locker()
index 68fbc3e7458d707c11851ee6935d848443d5756e..fb981585be2b6925311e34e58e54db649f3285a7 100644 (file)
@@ -21,6 +21,8 @@ type webseedPeer struct {
        activeRequests map[Request]webseed.Request
        requesterCond  sync.Cond
        peer           Peer
+       // Number of requester routines.
+       maxRequests int
 }
 
 var _ peerImpl = (*webseedPeer)(nil)
@@ -49,7 +51,7 @@ func (ws *webseedPeer) _cancel(r RequestIndex) bool {
                if !ws.peer.deleteRequest(r) {
                        panic("cancelled webseed request should exist")
                }
-               if ws.peer.actualRequestState.Requests.IsEmpty() {
+               if ws.peer.isLowOnRequests() {
                        ws.peer.updateRequests("webseedPeer._cancel")
                }
        }
@@ -158,3 +160,7 @@ func (ws *webseedPeer) requestResultHandler(r Request, webseedRequest webseed.Re
                }
        }
 }
+
+func (me *webseedPeer) isLowOnRequests() bool {
+       return me.peer.actualRequestState.Requests.GetCardinality() < uint64(me.maxRequests)
+}