t.go | 6 ++++++ torrent.go | 15 +++++++++++++++ tracker_scraper.go | 14 ++++++++++++++ webseed/client.go | 2 +- wstracker.go | 3 +++ diff --git a/t.go b/t.go index ba73d51851ff3411baf1885cd222b67bab1f7100..219656a6ce52d67d06ecfbe6bd77868342770a30 100644 --- a/t.go +++ b/t.go @@ -266,6 +266,12 @@ defer t.cl.unlock() 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 dfb980baefc74174bce92dca6d5ac65a5331d4c9..3a5d358c6c05f9360ee5a95854b59a1e036946df 100644 --- a/torrent.go +++ b/torrent.go @@ -1708,6 +1708,20 @@ t.startMissingTrackerScrapers() 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 @@ shortInfohash: shortInfohash, 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 0668c9127e872d61e734f1ebed039e2fd6e303fb..cc7ba423aae94727ded0d56f457f272b75279f14 100644 --- a/tracker_scraper.go +++ b/tracker_scraper.go @@ -7,6 +7,7 @@ "errors" "fmt" "net" "net/url" + "sync" "time" "github.com/anacrolix/dht/v2/krpc" @@ -23,11 +24,16 @@ u url.URL 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 @@ return false } } +func (me *trackerScraper) Stop() { + me.stopOnce.Do(func() { + close(me.stopCh) + }) +} + func (me *trackerScraper) Run() { defer me.announceStopped() @@ -252,6 +264,8 @@ reconsider = wantPeers } select { + case <-me.stopCh: + return case <-me.t.closed.Done(): return case <-reconsider: diff --git a/webseed/client.go b/webseed/client.go index 5e3c28b88522c22068e91e10234d552122f62cb9..7740fb8ed92e40bbe361c4db296edf492e604825 100644 --- a/webseed/client.go +++ b/webseed/client.go @@ -188,4 +188,4 @@ break } } return buf.Bytes(), err -} \ No newline at end of file +} diff --git a/wstracker.go b/wstracker.go index ff7b4b16007e3cc4cf9764a1b11113a6eb617d15..f94c3923b094995467d9b918da65a92136197e9d 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