From: ucwong <ucwong@126.com>
Date: Sun, 26 May 2024 11:47:04 +0000 (+0100)
Subject: add Torrent.ModifyTrackers() func (#945)
X-Git-Tag: v1.56.0~3
X-Git-Url: http://www.git.stargrave.org/?a=commitdiff_plain;h=7958f02e42be1898f340504c73a2b29bf1222877;p=btrtrc.git

add Torrent.ModifyTrackers() func (#945)

* add ClearTrackers() func

* add stop channel for each announcer

* add stop once avoid multi close

* use waitgroup to stop ann
---

diff --git a/t.go b/t.go
index ba73d518..219656a6 100644
--- a/t.go
+++ b/t.go
@@ -266,6 +266,12 @@ func (t *Torrent) AddTrackers(announceList [][]string) {
 	t.addTrackers(announceList)
 }
 
+func (t *Torrent) ModifyTrackers(announceList [][]string) {
+	t.cl.lock()
+	defer t.cl.unlock()
+	t.modifyTrackers(announceList)
+}
+
 func (t *Torrent) Piece(i pieceIndex) *Piece {
 	return t.piece(i)
 }
diff --git a/torrent.go b/torrent.go
index dfb980ba..3a5d358c 100644
--- a/torrent.go
+++ b/torrent.go
@@ -1708,6 +1708,20 @@ func (t *Torrent) addTrackers(announceList [][]string) {
 	t.updateWantPeersEvent()
 }
 
+func (t *Torrent) modifyTrackers(announceList [][]string) {
+	var workers errgroup.Group
+	for _, v := range t.trackerAnnouncers {
+		workers.Go(func() error {
+			v.Stop()
+			return nil
+		})
+	}
+	workers.Wait()
+
+	clear(t.metainfo.AnnounceList)
+	t.addTrackers(announceList)
+}
+
 // Don't call this before the info is available.
 func (t *Torrent) bytesCompleted() int64 {
 	if !t.haveInfo() {
@@ -1959,6 +1973,7 @@ func (t *Torrent) startScrapingTrackerWithInfohash(u *url.URL, urlStr string, sh
 			u:               *u,
 			t:               t,
 			lookupTrackerIp: t.cl.config.LookupTrackerIp,
+			stopCh:          make(chan struct{}),
 		}
 		go newAnnouncer.Run()
 		return newAnnouncer
diff --git a/tracker_scraper.go b/tracker_scraper.go
index 0668c912..cc7ba423 100644
--- a/tracker_scraper.go
+++ b/tracker_scraper.go
@@ -7,6 +7,7 @@ import (
 	"fmt"
 	"net"
 	"net/url"
+	"sync"
 	"time"
 
 	"github.com/anacrolix/dht/v2/krpc"
@@ -23,11 +24,16 @@ type trackerScraper struct {
 	t               *Torrent
 	lastAnnounce    trackerAnnounceResult
 	lookupTrackerIp func(*url.URL) ([]net.IP, error)
+
+	stopOnce sync.Once
+	stopCh   chan struct{}
 }
 
 type torrentTrackerAnnouncer interface {
 	statusLine() string
 	URL() *url.URL
+
+	Stop()
 }
 
 func (me trackerScraper) URL() *url.URL {
@@ -202,6 +208,12 @@ func (me *trackerScraper) canIgnoreInterval(notify *<-chan struct{}) bool {
 	}
 }
 
+func (me *trackerScraper) Stop() {
+	me.stopOnce.Do(func() {
+		close(me.stopCh)
+	})
+}
+
 func (me *trackerScraper) Run() {
 	defer me.announceStopped()
 
@@ -252,6 +264,8 @@ func (me *trackerScraper) Run() {
 		}
 
 		select {
+		case <-me.stopCh:
+			return
 		case <-me.t.closed.Done():
 			return
 		case <-reconsider:
diff --git a/webseed/client.go b/webseed/client.go
index 5e3c28b8..7740fb8e 100644
--- a/webseed/client.go
+++ b/webseed/client.go
@@ -188,4 +188,4 @@ func readRequestPartResponses(ctx context.Context, parts []requestPart) (_ []byt
 		}
 	}
 	return buf.Bytes(), err
-}
\ No newline at end of file
+}
diff --git a/wstracker.go b/wstracker.go
index ff7b4b16..f94c3923 100644
--- a/wstracker.go
+++ b/wstracker.go
@@ -31,6 +31,9 @@ func (me websocketTrackerStatus) URL() *url.URL {
 	return &me.url
 }
 
+func (me websocketTrackerStatus) Stop() {
+}
+
 type refCountedWebtorrentTrackerClient struct {
 	webtorrent.TrackerClient
 	refCount int