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
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
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]) {
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 {
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")
}
"iter"
"log/slog"
"math/rand"
+ "strings"
"sync"
"time"
hostKey webseedHostKeyHandle
}
+func (me *webseedPeer) peerImplWriteStatus(w io.Writer) {}
+
func (me *webseedPeer) isLowOnRequests() bool {
// Updates globally instead.
return false
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 {
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()
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)))):
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