]> Sergey Matveev's repositories - btrtrc.git/commitdiff
Fix panic writing webseed peer status
authorMatt Joiner <anacrolix@gmail.com>
Thu, 10 Jul 2025 14:10:06 +0000 (00:10 +1000)
committerMatt Joiner <anacrolix@gmail.com>
Thu, 10 Jul 2025 14:10:06 +0000 (00:10 +1000)
peer-impl.go
peer.go
webseed-peer.go
webseed-requesting.go

index 5586e43b4270cb2c1afa1d1c7b7eae1e3e22f58a..4bae3f8cd175441f3af095513d58748f95c2dbba 100644 (file)
@@ -1,10 +1,12 @@
 package torrent
 
 import (
+       "io"
+
        "github.com/RoaringBitmap/roaring"
-       pp "github.com/anacrolix/torrent/peer_protocol"
 
        "github.com/anacrolix/torrent/metainfo"
+       pp "github.com/anacrolix/torrent/peer_protocol"
 )
 
 // Contains implementation details that differ between peer types, like WebSeeds and regular
@@ -32,6 +34,7 @@ type legacyPeerImpl interface {
        String() string
        // Per peer-impl lines for WriteStatus.
        peerImplStatusLines() []string
+       peerImplWriteStatus(w io.Writer)
 
        // All if the peer should have everything, known if we know that for a fact. For example, we can
        // guess at how many pieces are in a torrent, and assume they have all pieces based on them
diff --git a/peer.go b/peer.go
index 9b031fb82cf6d168c875500c006e6da4de9947f5..a9e13d1efb7af970e72297b1c977c9ddc9d5adde 100644 (file)
--- a/peer.go
+++ b/peer.go
@@ -268,7 +268,7 @@ func (p *Peer) DownloadRate() float64 {
        return p.Stats().DownloadRate
 }
 
-func (cn *Peer) iterContiguousPieceRequests(f func(piece pieceIndex, count int)) {
+func (cn *PeerConn) iterContiguousPieceRequests(f func(piece pieceIndex, count int)) {
        var last Option[pieceIndex]
        var count int
        next := func(item Option[pieceIndex]) {
@@ -289,12 +289,7 @@ func (cn *Peer) iterContiguousPieceRequests(f func(piece pieceIndex, count int))
        next(None[pieceIndex]())
 }
 
-func (cn *Peer) writeStatus(w io.Writer) {
-       // \t isn't preserved in <pre> blocks?
-       if cn.closed.IsSet() {
-               fmt.Fprint(w, "CLOSED: ")
-       }
-       fmt.Fprintln(w, strings.Join(cn.peerImplStatusLines(), "\n"))
+func (cn *PeerConn) peerImplWriteStatus(w io.Writer) {
        prio, err := cn.peerPriority()
        prioStr := fmt.Sprintf("%08x", prio)
        if err != nil {
@@ -309,18 +304,30 @@ func (cn *Peer) writeStatus(w io.Writer) {
                cn.totalExpectingTime(),
        )
        fmt.Fprintf(w,
-               "%s completed, %d pieces touched, good chunks: %v/%v:%v dr: %.1f KiB/s\n",
+               "%s completed, chunks uploaded: %v\n",
                cn.completedString(),
-               len(cn.peerTouchedPieces),
-               &cn._stats.ChunksReadUseful,
-               &cn._stats.ChunksRead,
                &cn._stats.ChunksWritten,
-               cn.downloadRate()/(1<<10),
        )
        fmt.Fprintf(w, "requested pieces:")
        cn.iterContiguousPieceRequests(func(piece pieceIndex, count int) {
                fmt.Fprintf(w, " %v(%v)", piece, count)
        })
+}
+
+func (cn *Peer) writeStatus(w io.Writer) {
+       // \t isn't preserved in <pre> blocks?
+       if cn.closed.IsSet() {
+               fmt.Fprint(w, "CLOSED: ")
+       }
+       fmt.Fprintln(w, strings.Join(cn.peerImplStatusLines(), "\n"))
+       cn.peerImplWriteStatus(w)
+       fmt.Fprintf(w,
+               "%d pieces touched, good chunks: %v/%v, dr: %.1f KiB/s\n",
+               len(cn.peerTouchedPieces),
+               &cn._stats.ChunksReadUseful,
+               &cn._stats.ChunksRead,
+               cn.downloadRate()/(1<<10),
+       )
        fmt.Fprintf(w, "\n")
 }
 
index 80479e3b5166b7895a46746eb17ac0dbbd49c856..13b7794b5255725e9a1dcb3fcd7888d6c4cfad52 100644 (file)
@@ -7,6 +7,7 @@ import (
        "iter"
        "log/slog"
        "math/rand"
+       "strings"
        "sync"
        "time"
 
@@ -29,6 +30,8 @@ type webseedPeer struct {
        hostKey          webseedHostKeyHandle
 }
 
+func (me *webseedPeer) peerImplWriteStatus(w io.Writer) {}
+
 func (me *webseedPeer) isLowOnRequests() bool {
        // Updates globally instead.
        return false
@@ -58,10 +61,18 @@ func (me *webseedPeer) lastWriteUploadRate() float64 {
 var _ legacyPeerImpl = (*webseedPeer)(nil)
 
 func (me *webseedPeer) peerImplStatusLines() []string {
-       return []string{
+       lines := []string{
                me.client.Url,
                fmt.Sprintf("last unhandled error: %v", eventAgeString(me.lastUnhandledErr)),
        }
+       if len(me.activeRequests) > 0 {
+               elems := make([]string, 0, len(me.activeRequests))
+               for wr := range me.activeRequests {
+                       elems = append(elems, fmt.Sprintf("%v of [%v-%v)", wr.next, wr.begin, wr.end))
+               }
+               lines = append(lines, "active requests: "+strings.Join(elems, ", "))
+       }
+       return lines
 }
 
 func (ws *webseedPeer) String() string {
@@ -129,7 +140,7 @@ func (ws *webseedPeer) runRequest(webseedRequest *webseedRequest) {
        locker := ws.locker
        err := ws.readChunks(webseedRequest)
        if webseed.PrintDebug && webseedRequest.next < webseedRequest.end {
-               fmt.Printf("webseed peer stopped reading chunks early\n")
+               fmt.Printf("webseed peer stopped reading chunks early: %v\n", err)
        }
        // Ensure the body reader and response are closed.
        webseedRequest.Close()
@@ -142,7 +153,7 @@ func (ws *webseedPeer) runRequest(webseedRequest *webseedRequest) {
                torrent.Add("webseed request error count", 1)
                // This used to occur only on webseed.ErrTooFast but I think it makes sense to slow down any
                // kind of error. Pausing here will starve the available requester slots which slows things
-               // down.
+               // down. TODO: Use the Retry-After implementation from Erigon.
                select {
                case <-ws.peer.closed.Done():
                case <-time.After(time.Duration(rand.Int63n(int64(10 * time.Second)))):
index 0fb3d5792f80af043af952c70b3b2588edfddc8d..7ea252bacfc4dfcf91de77ba7ca7353f33aa276f 100644 (file)
@@ -12,10 +12,10 @@ import (
        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"
+       "github.com/anacrolix/torrent/webseed"
 )
 
 const defaultRequestsPerWebseedHost = 5