]> Sergey Matveev's repositories - btrtrc.git/commitdiff
Limit simultaneous announces to the same URL
authorMatt Joiner <anacrolix@gmail.com>
Thu, 1 Oct 2020 00:43:10 +0000 (10:43 +1000)
committerMatt Joiner <anacrolix@gmail.com>
Thu, 1 Oct 2020 00:43:10 +0000 (10:43 +1000)
client.go
torrent.go
tracker_scraper.go

index 6292d778fdbb31c5e6b82b6f421b44d625c3ffa5..7ae72295da5f38e8c20fd7ee681b46314f984b8a 100644 (file)
--- a/client.go
+++ b/client.go
@@ -78,6 +78,7 @@ type Client struct {
        numHalfOpen     int
 
        websocketTrackers websocketTrackers
+       activeAnnounces   map[string]struct{}
 }
 
 type ipStr string
index 21069ec5fe0cd0324b42aaf2a460f01dc36a9785..3c0bcb09275282a509aac7e8cccd21dc53eba1c4 100644 (file)
@@ -1411,9 +1411,32 @@ func (t *Torrent) startScrapingTracker(_url string) {
                                return nil
                        }
                }
+               urlString := (*u).String()
+               cl := t.cl
                newAnnouncer := &trackerScraper{
                        u: *u,
                        t: t,
+                       allow: func() {
+                               cl.lock()
+                               defer cl.unlock()
+                               if cl.activeAnnounces == nil {
+                                       cl.activeAnnounces = make(map[string]struct{})
+                               }
+                               for {
+                                       if _, ok := cl.activeAnnounces[urlString]; ok {
+                                               cl.event.Wait()
+                                       } else {
+                                               break
+                                       }
+                               }
+                               cl.activeAnnounces[urlString] = struct{}{}
+                       },
+                       done: func() {
+                               cl.lock()
+                               defer cl.unlock()
+                               delete(cl.activeAnnounces, urlString)
+                               cl.event.Broadcast()
+                       },
                }
                go newAnnouncer.Run()
                return newAnnouncer
index 1323795398496a0893b51c9b2e32d6de6f0cfd31..b7d38c5aab993c287b3c6eae071594d6409cb8cb 100644 (file)
@@ -20,6 +20,7 @@ type trackerScraper struct {
        u            url.URL
        t            *Torrent
        lastAnnounce trackerAnnounceResult
+       allow, done  func()
 }
 
 type torrentTrackerAnnouncer interface {
@@ -108,6 +109,8 @@ func (me *trackerScraper) announce(event tracker.AnnounceEvent) (ret trackerAnno
                ret.Completed = time.Now()
        }()
        ret.Interval = time.Minute
+       me.allow()
+       defer me.done()
        ip, err := me.getIp()
        if err != nil {
                ret.Err = fmt.Errorf("error getting ip: %s", err)