From 3226dc1ccd928eaaa5dd6f55124cc45b4c16577f Mon Sep 17 00:00:00 2001
From: Matt Joiner <anacrolix@gmail.com>
Date: Wed, 22 Apr 2020 11:42:31 +1000
Subject: [PATCH] Rename per-torrent ws tracker and output stats

---
 torrent.go                   |  2 +-
 webtorrent/tracker_client.go | 20 ++++++++++++++++++++
 wstracker.go                 | 10 +++++-----
 3 files changed, 26 insertions(+), 6 deletions(-)

diff --git a/torrent.go b/torrent.go
index 11fb8eba..0117094a 100644
--- a/torrent.go
+++ b/torrent.go
@@ -1330,7 +1330,7 @@ func (t *Torrent) startWebsocketAnnouncer(u url.URL) torrentTrackerAnnouncer {
 		<-t.closed.LockedChan(t.cl.locker())
 		release()
 	}()
-	wst := websocketTracker{u, wtc}
+	wst := websocketTrackerStatus{u, wtc}
 	go func() {
 		err := wtc.Announce(tracker.Started, t.infoHash)
 		if err != nil {
diff --git a/webtorrent/tracker_client.go b/webtorrent/tracker_client.go
index 14b62ed2..0948cdcd 100644
--- a/webtorrent/tracker_client.go
+++ b/webtorrent/tracker_client.go
@@ -15,6 +15,12 @@ import (
 	"github.com/pion/webrtc/v2"
 )
 
+type TrackerClientStats struct {
+	Dials                  int64
+	ConvertedInboundConns  int64
+	ConvertedOutboundConns int64
+}
+
 // Client represents the webtorrent client
 type TrackerClient struct {
 	Url                string
@@ -28,6 +34,13 @@ type TrackerClient struct {
 	outboundOffers map[string]outboundOffer // OfferID to outboundOffer
 	wsConn         *websocket.Conn
 	closed         bool
+	stats          TrackerClientStats
+}
+
+func (me *TrackerClient) Stats() TrackerClientStats {
+	me.mu.Lock()
+	defer me.mu.Unlock()
+	return me.stats
 }
 
 func (me *TrackerClient) peerIdBinary() string {
@@ -53,6 +66,7 @@ type onDataChannelOpen func(_ datachannel.ReadWriteCloser, dcc DataChannelContex
 
 func (tc *TrackerClient) doWebsocket() error {
 	metrics.Add("websocket dials", 1)
+	tc.stats.Dials++
 	c, _, err := websocket.DefaultDialer.Dial(tc.Url, nil)
 	if err != nil {
 		return fmt.Errorf("dialing tracker: %w", err)
@@ -232,6 +246,9 @@ func (tc *TrackerClient) handleOffer(
 		setDataChannelOnOpen(d, peerConnection, func(dc datachannel.ReadWriteCloser) {
 			timer.Stop()
 			metrics.Add("answering peer connection conversions", 1)
+			tc.mu.Lock()
+			tc.stats.ConvertedInboundConns++
+			tc.mu.Unlock()
 			tc.OnConn(dc, DataChannelContext{
 				Local:        answer,
 				Remote:       offer,
@@ -256,6 +273,9 @@ func (tc *TrackerClient) handleAnswer(offerId string, answer webrtc.SessionDescr
 	metrics.Add("outbound offers answered", 1)
 	err := offer.setAnswer(answer, func(dc datachannel.ReadWriteCloser) {
 		metrics.Add("outbound offers answered with datachannel", 1)
+		tc.mu.Lock()
+		tc.stats.ConvertedOutboundConns++
+		tc.mu.Unlock()
 		tc.OnConn(dc, DataChannelContext{
 			Local:        offer.originalOffer,
 			Remote:       answer,
diff --git a/wstracker.go b/wstracker.go
index 95780d77..6f376c55 100644
--- a/wstracker.go
+++ b/wstracker.go
@@ -12,16 +12,16 @@ import (
 	"github.com/pion/datachannel"
 )
 
-type websocketTracker struct {
+type websocketTrackerStatus struct {
 	url url.URL
-	*webtorrent.TrackerClient
+	tc  *webtorrent.TrackerClient
 }
 
-func (me websocketTracker) statusLine() string {
-	return fmt.Sprintf("%q", me.url.String())
+func (me websocketTrackerStatus) statusLine() string {
+	return fmt.Sprintf("%q: %+v", me.tc.Url, me.tc.Stats())
 }
 
-func (me websocketTracker) URL() url.URL {
+func (me websocketTrackerStatus) URL() url.URL {
 	return me.url
 }
 
-- 
2.51.0