--- /dev/null
+package torrent
+
+type ClientStats struct {
+ ConnStats
+
+ // Ongoing outgoing dial attempts. There may be more than one dial going on per peer address due
+ // to hole-punch connect requests. The total may not match the sum of attempts for all Torrents
+ // if a Torrent is dropped while there are outstanding dials.
+ ActiveHalfOpenAttempts int
+}
type Client struct {
// An aggregate of stats over all connections. First in struct to ensure 64-bit alignment of
// fields. See #262.
- stats ConnStats
+ connStats ConnStats
_mu lockWithDeferreds
event sync.Cond
fmt.Fprintf(w, "%s DHT server at %s:\n", s.Addr().Network(), s.Addr().String())
writeDhtServerStatus(w, s)
})
- spew.Fdump(w, &cl.stats)
+ dumpStats(w, cl.statsLocked())
torrentsSlice := cl.torrentsAsSlice()
fmt.Fprintf(w, "# Torrents: %d\n", len(torrentsSlice))
fmt.Fprintln(w)
func (cl *Client) countHalfOpenFromTorrents() (count int) {
for _, t := range cl.torrents {
- for _, attempts := range t.halfOpen {
- count += len(attempts)
- }
+ count += t.numHalfOpenAttempts()
}
return
}
return fmt.Sprintf("<%[1]T %[1]p>", cl)
}
-// Returns connection-level aggregate stats at the Client level. See the comment on
+// Returns connection-level aggregate connStats at the Client level. See the comment on
// TorrentStats.ConnStats.
func (cl *Client) ConnStats() ConnStats {
- return cl.stats.Copy()
+ return cl.connStats.Copy()
+}
+
+func (cl *Client) Stats() ClientStats {
+ cl.rLock()
+ defer cl.rUnlock()
+ return cl.statsLocked()
+}
+
+func (cl *Client) statsLocked() (stats ClientStats) {
+ stats.ConnStats = cl.connStats.Copy()
+ stats.ActiveHalfOpenAttempts = cl.numHalfOpen
+ return
}
func (cn *Peer) postHandshakeStats(f func(*ConnStats)) {
t := cn.t
f(&t.stats)
- f(&t.cl.stats)
+ f(&t.cl.connStats)
}
// All ConnStats that include this connection. Some objects are not known
--- /dev/null
+package torrent
+
+import (
+ "io"
+
+ "github.com/davecgh/go-spew/spew"
+)
+
+func dumpStats[T any](w io.Writer, stats T) {
+ spew.NewDefaultConfig()
+ spew.Fdump(w, stats)
+}
"github.com/anacrolix/missinggo/v2/pubsub"
"github.com/anacrolix/multiless"
"github.com/anacrolix/sync"
- "github.com/davecgh/go-spew/spew"
"github.com/pion/datachannel"
"golang.org/x/exp/maps"
fmt.Fprintf(w, "DHT Announces: %d\n", t.numDHTAnnounces)
- spew.NewDefaultConfig()
- spew.Fdump(w, t.statsLocked())
+ dumpStats(w, t.statsLocked())
fmt.Fprintf(w, "webseeds:\n")
t.writePeerStatuses(w, maps.Values(t.webSeeds))
// connection.
func (t *Torrent) allStats(f func(*ConnStats)) {
f(&t.stats)
- f(&t.cl.stats)
+ f(&t.cl.connStats)
}
func (t *Torrent) hashingPiece(i pieceIndex) bool {
}
return
}
+
+func (t *Torrent) numHalfOpenAttempts() (num int) {
+ for _, attempts := range t.halfOpen {
+ num += len(attempts)
+ }
+ return
+}