From: Matt Joiner Date: Tue, 2 May 2023 07:09:43 +0000 (+1000) Subject: Add Client.Stats with ActiveHalfOpenAttempts X-Git-Url: http://www.git.stargrave.org/?a=commitdiff_plain;h=884b71ea6d0cd9409e6c205d17be53ba29738499;p=btrtrc.git Add Client.Stats with ActiveHalfOpenAttempts --- diff --git a/client-stats.go b/client-stats.go new file mode 100644 index 00000000..d799bae6 --- /dev/null +++ b/client-stats.go @@ -0,0 +1,10 @@ +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 +} diff --git a/client.go b/client.go index 709bc4c0..65545973 100644 --- a/client.go +++ b/client.go @@ -57,7 +57,7 @@ import ( 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 @@ -149,7 +149,7 @@ func (cl *Client) WriteStatus(_w io.Writer) { 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) @@ -694,9 +694,7 @@ func (cl *Client) noLongerHalfOpen(t *Torrent, addr string, attemptKey outgoingC func (cl *Client) countHalfOpenFromTorrents() (count int) { for _, t := range cl.torrents { - for _, attempts := range t.halfOpen { - count += len(attempts) - } + count += t.numHalfOpenAttempts() } return } @@ -1783,8 +1781,20 @@ func (cl *Client) String() string { 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 } diff --git a/peer.go b/peer.go index 1d8ead10..4f783137 100644 --- a/peer.go +++ b/peer.go @@ -519,7 +519,7 @@ func (cn *Peer) peerPiecesChanged() { 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 diff --git a/stats.go b/stats.go new file mode 100644 index 00000000..90144bf7 --- /dev/null +++ b/stats.go @@ -0,0 +1,12 @@ +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) +} diff --git a/torrent_stats.go b/torrent-stats.go similarity index 100% rename from torrent_stats.go rename to torrent-stats.go diff --git a/torrent.go b/torrent.go index 41848e4a..7ad67b2b 100644 --- a/torrent.go +++ b/torrent.go @@ -31,7 +31,6 @@ import ( "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" @@ -767,8 +766,7 @@ func (t *Torrent) writeStatus(w io.Writer) { 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)) @@ -2455,7 +2453,7 @@ func (t *Torrent) AddClientPeer(cl *Client) int { // 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 { @@ -2859,3 +2857,10 @@ func (t *Torrent) startHolepunchRendezvous(addrPort netip.AddrPort) (rz *utHolep } return } + +func (t *Torrent) numHalfOpenAttempts() (num int) { + for _, attempts := range t.halfOpen { + num += len(attempts) + } + return +}