7 "github.com/anacrolix/missinggo"
9 "github.com/anacrolix/torrent/tracker"
12 // Announces a torrent to a tracker at regular intervals, when peers are
14 type trackerScraper struct {
16 // Causes the trackerScraper to stop running.
21 func trackerToTorrentPeers(ps []tracker.Peer) (ret []Peer) {
22 ret = make([]Peer, 0, len(ps))
23 for _, p := range ps {
24 ret = append(ret, Peer{
27 Source: peerSourceTracker,
33 // Return how long to wait before trying again. For most errors, we return 5
34 // minutes, a relatively quick turn around for DNS changes.
35 func (me *trackerScraper) announce() time.Duration {
36 blocked, urlToUse, host, err := me.t.cl.prepareTrackerAnnounceUnlocked(me.url)
38 log.Printf("error preparing announce to %q: %s", me.url, err)
39 return 5 * time.Minute
42 log.Printf("announce to tracker %q blocked by IP", me.url)
43 return 5 * time.Minute
46 req := me.t.announceRequest()
48 res, err := tracker.AnnounceHost(urlToUse, &req, host)
50 log.Printf("error announcing %s %q to %q: %s", me.t.InfoHash().HexString(), me.t.Name(), me.url, err)
51 return 5 * time.Minute
53 me.t.AddPeers(trackerToTorrentPeers(res.Peers))
54 return time.Duration(res.Interval) * time.Second
57 func (me *trackerScraper) Run() {
60 case <-me.t.closed.LockedChan(&me.t.cl.mu):
62 case <-me.stop.LockedChan(&me.t.cl.mu):
64 case <-me.t.wantPeersEvent.LockedChan(&me.t.cl.mu):
67 intervalChan := time.After(me.announce())
70 case <-me.t.closed.LockedChan(&me.t.cl.mu):
72 case <-me.stop.LockedChan(&me.t.cl.mu):