]> Sergey Matveev's repositories - btrtrc.git/commitdiff
Fix proposed and existing cancelled webseed requests colliding in priority heap
authorMatt Joiner <anacrolix@gmail.com>
Wed, 6 Aug 2025 10:36:29 +0000 (20:36 +1000)
committerMatt Joiner <anacrolix@gmail.com>
Wed, 6 Aug 2025 10:36:29 +0000 (20:36 +1000)
webseed-requesting.go

index abb297addb7f6138887c028e10d74be8d2d9274f..821e55b6f3a3e5ba64cb2d1c9402e14f83ab1051 100644 (file)
@@ -18,6 +18,7 @@ import (
        g "github.com/anacrolix/generics"
        "github.com/anacrolix/generics/heap"
        "github.com/anacrolix/missinggo/v2/panicif"
+       "github.com/davecgh/go-spew/spew"
 
        "github.com/anacrolix/torrent/internal/request-strategy"
        "github.com/anacrolix/torrent/metainfo"
@@ -139,7 +140,12 @@ func (cl *Client) updateWebseedRequests() {
                                // Doing earlier chunks first means more compact files for partial file hashing.
                                cmp.Compare(l.sliceIndex, r.sliceIndex),
                        )
-                       panicif.Zero(ret)
+                       if ret == 0 {
+                               cfg := spew.NewDefaultConfig()
+                               cfg.Dump(l)
+                               cfg.Dump(r)
+                               panic("webseed request heap ordering is not stable")
+                       }
                        return ret < 0
                },
        )
@@ -417,6 +423,12 @@ func (cl *Client) iterCurrentWebseedRequests() iter.Seq2[webseedUniqueRequestKey
                                                // This request is done, so don't yield it.
                                                continue
                                        }
+                                       if ar.cancelled.Load() {
+                                               cl.slogger.Debug("iter current webseed requests: skipped cancelled webseed request")
+                                               // This should prevent overlapping webseed requests that are just filling
+                                               // slots waiting to cancel from conflicting.
+                                               continue
+                                       }
                                        p := t.piece(t.pieceIndexOfRequestIndex(ar.next))
                                        if !yield(
                                                webseedUniqueRequestKey{