Break up the DHT announcer code into smaller functions, and add a 5 minute delay between announces

This commit is contained in:
Matt Joiner 2016-07-23 22:38:31 +10:00
parent 5cc735ef32
commit 980cd69ab2
2 changed files with 67 additions and 49 deletions

View File

@ -1473,7 +1473,7 @@ func (cl *Client) AddTorrentInfoHash(infoHash metainfo.Hash) (t *Torrent, new bo
new = true new = true
t = cl.newTorrent(infoHash) t = cl.newTorrent(infoHash)
if cl.dHT != nil { if cl.dHT != nil {
go t.announceDHT(true) go t.dhtAnnouncer()
} }
cl.torrents[infoHash] = t cl.torrents[infoHash] = t
t.updateWantPeersEvent() t.updateWantPeersEvent()

View File

@ -23,6 +23,7 @@ import (
"github.com/bradfitz/iter" "github.com/bradfitz/iter"
"github.com/anacrolix/torrent/bencode" "github.com/anacrolix/torrent/bencode"
"github.com/anacrolix/torrent/dht"
"github.com/anacrolix/torrent/metainfo" "github.com/anacrolix/torrent/metainfo"
pp "github.com/anacrolix/torrent/peer_protocol" pp "github.com/anacrolix/torrent/peer_protocol"
"github.com/anacrolix/torrent/storage" "github.com/anacrolix/torrent/storage"
@ -1208,31 +1209,17 @@ func (t *Torrent) announceRequest() tracker.AnnounceRequest {
} }
} }
func (t *Torrent) announceDHT(impliedPort bool) { // Adds peers revealed in an announce until the announce ends, or we have
// enough peers.
func (t *Torrent) consumeDHTAnnounce(pvs <-chan dht.PeersValues) {
cl := t.cl cl := t.cl
for {
select {
case <-t.wantPeersEvent.LockedChan(&cl.mu):
case <-t.closed.LockedChan(&cl.mu):
return
}
// log.Printf("getting peers for %q from DHT", t)
ps, err := cl.dHT.Announce(string(t.infoHash[:]), cl.incomingPeerPort(), impliedPort)
if err != nil {
log.Printf("error getting peers from dht: %s", err)
return
}
cl.mu.Lock()
t.numDHTAnnounces++
cl.mu.Unlock()
// Count all the unique addresses we got during this announce. // Count all the unique addresses we got during this announce.
allAddrs := make(map[string]struct{}) allAddrs := make(map[string]struct{})
getPeers:
for { for {
select { select {
case v, ok := <-ps.Peers: case v, ok := <-pvs:
if !ok { if !ok {
break getPeers return
} }
addPeers := make([]Peer, 0, len(v.Peers)) addPeers := make([]Peer, 0, len(v.Peers))
for _, cp := range v.Peers { for _, cp := range v.Peers {
@ -1256,15 +1243,46 @@ func (t *Torrent) announceDHT(impliedPort bool) {
numPeers := len(t.peers) numPeers := len(t.peers)
cl.mu.Unlock() cl.mu.Unlock()
if numPeers >= torrentPeersHighWater { if numPeers >= torrentPeersHighWater {
break getPeers return
} }
case <-t.closed.LockedChan(&cl.mu): case <-t.closed.LockedChan(&cl.mu):
ps.Close()
return return
} }
} }
}
func (t *Torrent) announceDHT(impliedPort bool) (err error) {
cl := t.cl
ps, err := cl.dHT.Announce(string(t.infoHash[:]), cl.incomingPeerPort(), impliedPort)
if err != nil {
return
}
t.consumeDHTAnnounce(ps.Peers)
ps.Close() ps.Close()
// log.Printf("finished DHT peer scrape for %s: %d peers", t, len(allAddrs)) return
}
func (t *Torrent) dhtAnnouncer() {
cl := t.cl
for {
select {
case <-t.wantPeersEvent.LockedChan(&cl.mu):
case <-t.closed.LockedChan(&cl.mu):
return
}
err := t.announceDHT(true)
if err == nil {
cl.mu.Lock()
t.numDHTAnnounces++
cl.mu.Unlock()
} else {
log.Printf("error announcing %q to DHT: %s", t, err)
}
select {
case <-t.closed.LockedChan(&cl.mu):
return
case <-time.After(5 * time.Minute):
}
} }
} }