]> Sergey Matveev's repositories - btrtrc.git/commitdiff
Improve some webseed debugging
authorMatt Joiner <anacrolix@gmail.com>
Wed, 2 Jul 2025 05:10:51 +0000 (15:10 +1000)
committerMatt Joiner <anacrolix@gmail.com>
Wed, 2 Jul 2025 05:12:59 +0000 (15:12 +1000)
fmt.go [new file with mode: 0644]
webseed-requesting.go

diff --git a/fmt.go b/fmt.go
new file mode 100644 (file)
index 0000000..7249f50
--- /dev/null
+++ b/fmt.go
@@ -0,0 +1,14 @@
+package torrent
+
+import (
+       "fmt"
+       "strings"
+)
+
+func formatMap[K comparable, V any](m map[K]V) string {
+       var sb strings.Builder
+       for k, v := range m {
+               fmt.Fprintf(&sb, "%v: %v\n", k, v)
+       }
+       return strings.TrimSuffix(sb.String(), "\n")
+}
index 7a001603ddb2f52c0c2b6d00e4cb9479bf1ede4d..68b8e8905374f06cf4af2b4b4065755bd977a923 100644 (file)
@@ -2,13 +2,17 @@ package torrent
 
 import (
        "cmp"
+       "fmt"
        "iter"
        "maps"
+       "strings"
+       "sync"
        "unique"
 
        g "github.com/anacrolix/generics"
        "github.com/anacrolix/generics/heap"
        "github.com/anacrolix/missinggo/v2/panicif"
+       "github.com/anacrolix/torrent/webseed"
 
        "github.com/anacrolix/torrent/internal/request-strategy"
        "github.com/anacrolix/torrent/metainfo"
@@ -118,10 +122,20 @@ func (cl *Client) globalUpdateWebSeedRequests() {
 
        // Cancel any existing requests that are no longer wanted.
        for key, value := range unwantedExistingRequests {
+               if webseed.PrintDebug {
+                       fmt.Printf("cancelling deprioritized existing webseed request %v\n", key)
+               }
                key.t.slogger().Debug("cancelling deprioritized existing webseed request", "webseedUrl", key.url, "fileIndex", key.fileIndex)
                value.existingWebseedRequest.Cancel()
        }
 
+       printPlan := sync.OnceFunc(func() {
+               if webseed.PrintDebug {
+                       //fmt.Println(plan)
+                       //fmt.Println(formatMap(existingRequests))
+               }
+       })
+
        for costKey, requestKeys := range plan.byCost {
                for _, requestKey := range requestKeys {
                        // This could happen if a request is cancelled but hasn't removed itself from the active
@@ -135,9 +149,13 @@ func (cl *Client) globalUpdateWebSeedRequests() {
                        t := requestKey.t
                        // Run the request to the end of the file for now. TODO: Set a reasonable end so the
                        // remote doesn't oversend.
-                       t.webSeeds[requestKey.url].spawnRequest(
-                               t.getRequestIndexContainingOffset(requestKey.startOffset),
-                               t.endRequestIndexForFileIndex(requestKey.fileIndex))
+                       peer := t.webSeeds[requestKey.url]
+                       panicif.NotEq(peer.hostKey, costKey)
+                       printPlan()
+                       begin := t.getRequestIndexContainingOffset(requestKey.startOffset)
+                       end := t.endRequestIndexForFileIndex(requestKey.fileIndex)
+                       panicif.Eq(begin, end)
+                       peer.spawnRequest(begin, end)
                }
        }
 }
@@ -146,6 +164,17 @@ type webseedRequestPlan struct {
        byCost map[webseedHostKeyHandle][]webseedUniqueRequestKey
 }
 
+func (me webseedRequestPlan) String() string {
+       var sb strings.Builder
+       for costKey, requestKeys := range me.byCost {
+               fmt.Fprintf(&sb, "%v\n", costKey.Value())
+               for _, requestKey := range requestKeys {
+                       fmt.Fprintf(&sb, "\t%v\n", requestKey)
+               }
+       }
+       return strings.TrimSuffix(sb.String(), "\n")
+}
+
 // Distinct webseed request data when different offsets are not allowed.
 type aprioriWebseedRequestKey struct {
        t         *Torrent
@@ -153,12 +182,20 @@ type aprioriWebseedRequestKey struct {
        url       webseedUrlKey
 }
 
+func (me aprioriWebseedRequestKey) String() string {
+       return fmt.Sprintf("%v from %v", me.t.Files()[me.fileIndex].Path(), me.url)
+}
+
 // Distinct webseed request when different offsets to the same object are allowed.
 type webseedUniqueRequestKey struct {
        aprioriWebseedRequestKey
        startOffset int64
 }
 
+func (me webseedUniqueRequestKey) String() string {
+       return me.aprioriWebseedRequestKey.String() + " at " + fmt.Sprintf("0x%x", me.startOffset)
+}
+
 // Non-distinct proposed webseed request data.
 type webseedRequestOrderValue struct {
        priority PiecePriority
@@ -169,8 +206,11 @@ type webseedRequestOrderValue struct {
        costKey webseedHostKeyHandle
 }
 
-// Yields possible webseed requests by piece. Caller should filter and prioritize these. TODO:
-// Doesn't handle dirty chunks.
+func (me webseedRequestOrderValue) String() string {
+       return fmt.Sprintf("%#v", me)
+}
+
+// Yields possible webseed requests by piece. Caller should filter and prioritize these.
 func (cl *Client) iterWebseed() iter.Seq2[webseedUniqueRequestKey, webseedRequestOrderValue] {
        return func(yield func(webseedUniqueRequestKey, webseedRequestOrderValue) bool) {
                for key, value := range cl.pieceRequestOrder {