From 98f188dcbef1b62cdcd6e91fdc3abf16113b2b5a Mon Sep 17 00:00:00 2001 From: Matt Joiner Date: Mon, 13 Dec 2021 12:09:12 +1100 Subject: [PATCH] Update requests after deleting all in some corner cases Choked by non-fast PeerConn, deleted PeerConn. They're not exactly guarded as strictly as they could be, so there's plenty of room for performance improvements here. --- peerconn.go | 23 ++++++++++++++++++++--- torrent.go | 8 +++++++- webseed-peer.go | 5 +++++ 3 files changed, 32 insertions(+), 4 deletions(-) diff --git a/peerconn.go b/peerconn.go index 4ec0944b..0083a073 100644 --- a/peerconn.go +++ b/peerconn.go @@ -1095,7 +1095,13 @@ func (c *PeerConn) mainReadLoop() (err error) { break } if !c.fastEnabled() { - c.deleteAllRequests() + if !c.deleteAllRequests().IsEmpty() { + c.t.iterPeers(func(p *Peer) { + if p.isLowOnRequests() { + p.updateRequests("choked by non-fast PeerConn") + } + }) + } } else { // We don't decrement pending requests here, let's wait for the peer to either // reject or satisfy the outstanding requests. Additionally, some peers may unchoke @@ -1554,16 +1560,27 @@ func (c *Peer) deleteRequest(r RequestIndex) bool { } delete(c.t.pendingRequests, r) delete(c.t.lastRequested, r) + // c.t.iterPeers(func(p *Peer) { + // if p.isLowOnRequests() { + // p.updateRequests("Peer.deleteRequest") + // } + // }) return true } -func (c *Peer) deleteAllRequests() { - c.requestState.Requests.Clone().Iterate(func(x uint32) bool { +func (c *Peer) deleteAllRequests() (deleted *roaring.Bitmap) { + deleted = c.requestState.Requests.Clone() + deleted.Iterate(func(x uint32) bool { if !c.deleteRequest(x) { panic("request should exist") } return true }) + c.assertNoRequests() + return +} + +func (c *Peer) assertNoRequests() { if !c.requestState.Requests.IsEmpty() { panic(c.requestState.Requests.GetCardinality()) } diff --git a/torrent.go b/torrent.go index c41b213b..5c8dca25 100644 --- a/torrent.go +++ b/torrent.go @@ -1396,7 +1396,13 @@ func (t *Torrent) deletePeerConn(c *PeerConn) (ret bool) { } } torrent.Add("deleted connections", 1) - c.deleteAllRequests() + if !c.deleteAllRequests().IsEmpty() { + t.iterPeers(func(p *Peer) { + if p.isLowOnRequests() { + p.updateRequests("Torrent.deletePeerConn") + } + }) + } t.assertPendingRequests() return } diff --git a/webseed-peer.go b/webseed-peer.go index 221aa53f..08a7be2c 100644 --- a/webseed-peer.go +++ b/webseed-peer.go @@ -133,6 +133,11 @@ func (ws *webseedPeer) onClose() { for _, r := range ws.activeRequests { r.Cancel() } + ws.peer.t.iterPeers(func(p *Peer) { + if p.isLowOnRequests() { + p.updateRequests("webseedPeer.onClose") + } + }) ws.requesterCond.Broadcast() } -- 2.50.0