]> Sergey Matveev's repositories - btrtrc.git/commitdiff
Track activeWebseedRequests in Client too
authorMatt Joiner <anacrolix@gmail.com>
Thu, 14 Aug 2025 02:36:12 +0000 (12:36 +1000)
committerMatt Joiner <anacrolix@gmail.com>
Thu, 14 Aug 2025 02:36:12 +0000 (12:36 +1000)
client.go
torrent.go
webseed-peer.go

index f2b4aefd590a4490e8c017dc9d18484b73ab6789..99494b2ce5a4fb969c0de5443d0dc64c89d604e2 100644 (file)
--- a/client.go
+++ b/client.go
@@ -113,8 +113,9 @@ type Client struct {
 
        upnpMappings []*upnpMapping
 
-       webseedRequestTimer *time.Timer
-       webseedUpdateReason updateRequestReason
+       webseedRequestTimer   *time.Timer
+       webseedUpdateReason   updateRequestReason
+       activeWebseedRequests map[webseedUniqueRequestKey]*webseedRequest
 
        activePieceHashers int
 }
index 44961c2b2f3562366b9e80715444ee07ac3fe6f6..2f6b7b98f838f2f89f7ebffe0b0989a177b32b58 100644 (file)
@@ -1115,6 +1115,13 @@ func (t *Torrent) close(wg *sync.WaitGroup) {
        t.pieceStateChanges.Close()
        t.updateWantPeersEvent()
        g.MustDelete(t.cl.torrents, t)
+       // This doesn't work yet because requests remove themselves after they close, and we don't
+       // remove them synchronously.
+       if false {
+               if len(t.cl.torrents) == 0 {
+                       panicif.NotZero(len(t.cl.activeWebseedRequests))
+               }
+       }
        return
 }
 
@@ -3085,7 +3092,8 @@ func (t *Torrent) addWebSeed(url string, opts ...AddWebSeedsOpt) bool {
        if t.cl.config.DisableWebseeds {
                return false
        }
-       if _, ok := t.webSeeds[webseedUrlKey(unique.Make(url))]; ok {
+       urlKey := webseedUrlKey(unique.Make(url))
+       if _, ok := t.webSeeds[urlKey]; ok {
                return false
        }
        // I don't think Go http supports pipelining requests. However, we can have more ready to go
@@ -3113,6 +3121,7 @@ func (t *Torrent) addWebSeed(url string, opts ...AddWebSeedsOpt) bool {
                        ResponseBodyRateLimiter: t.cl.config.DownloadRateLimiter,
                },
                hostKey: t.deriveWebSeedHostKey(url),
+               url:     urlKey,
        }
        ws.peer.initClosedCtx()
        for _, opt := range opts {
@@ -3136,7 +3145,7 @@ func (t *Torrent) addWebSeed(url string, opts ...AddWebSeedsOpt) bool {
        if t.haveInfo() {
                ws.onGotInfo(t.info)
        }
-       t.webSeeds[webseedUrlKey(unique.Make(url))] = &ws
+       t.webSeeds[urlKey] = &ws
        ws.peer.onNeedUpdateRequests("Torrent.addWebSeed")
        return true
 }
index 4f84a5fa2f5872bcd753322aeee3cd238f1828c6..19ace3142422f78c1c6b48c365ca21aa6045c047 100644 (file)
@@ -30,6 +30,8 @@ type webseedPeer struct {
        locker           sync.Locker
        lastUnhandledErr time.Time
        hostKey          webseedHostKeyHandle
+       // We need this to look ourselves up in the Client.activeWebseedRequests map.
+       url webseedUrlKey
 }
 
 func (*webseedPeer) allConnStatsImplField(stats *AllConnStats) *ConnStats {
@@ -132,6 +134,10 @@ func (ws *webseedPeer) spawnRequest(begin, end RequestIndex, logger *slog.Logger
                ws.peer.t.cl.dumpCurrentWebseedRequests()
        }
        ws.activeRequests[&wsReq] = struct{}{}
+       t := ws.peer.t
+       cl := t.cl
+       g.MakeMapIfNil(&cl.activeWebseedRequests)
+       g.MapMustAssignNew(cl.activeWebseedRequests, ws.getRequestKey(&wsReq), &wsReq)
        ws.peer.updateExpectingChunks()
        panicif.Zero(ws.hostKey)
        ws.peer.t.cl.numWebSeedRequests[ws.hostKey]++
@@ -144,6 +150,15 @@ func (ws *webseedPeer) spawnRequest(begin, end RequestIndex, logger *slog.Logger
        go ws.runRequest(&wsReq)
 }
 
+func (me *webseedPeer) getRequestKey(wr *webseedRequest) webseedUniqueRequestKey {
+       // This is used to find the request in the Client's active requests map.
+       return webseedUniqueRequestKey{
+               url:        me.url,
+               t:          me.peer.t,
+               sliceIndex: me.peer.t.requestIndexToWebseedSliceIndex(wr.begin),
+       }
+}
+
 func (me *webseedPeer) hasOverlappingRequests(begin, end RequestIndex) bool {
        for req := range me.activeRequests {
                if req.cancelled.Load() {
@@ -210,7 +225,9 @@ func (ws *webseedPeer) runRequest(webseedRequest *webseedRequest) {
 
 func (ws *webseedPeer) deleteActiveRequest(wr *webseedRequest) {
        g.MustDelete(ws.activeRequests, wr)
-       ws.peer.t.cl.numWebSeedRequests[ws.hostKey]--
+       cl := ws.peer.cl
+       cl.numWebSeedRequests[ws.hostKey]--
+       g.MustDelete(cl.activeWebseedRequests, ws.getRequestKey(wr))
        ws.peer.updateExpectingChunks()
 }