Merge pull request #1309 from fjl/p2p-fix-lookup-spin

p2p: throttle all discovery lookups
This commit is contained in:
Jeffrey Wilcke 2015-06-23 05:36:58 -07:00
commit 139439dcdc
2 changed files with 16 additions and 15 deletions

View File

@ -17,10 +17,9 @@ const (
// redialing a certain node. // redialing a certain node.
dialHistoryExpiration = 30 * time.Second dialHistoryExpiration = 30 * time.Second
// Discovery lookup tasks will wait for this long when // Discovery lookups are throttled and can only run
// no results are returned. This can happen if the table // once every few seconds.
// becomes empty (i.e. not often). lookupInterval = 4 * time.Second
emptyLookupDelay = 10 * time.Second
) )
// dialstate schedules dials and discovery lookups. // dialstate schedules dials and discovery lookups.
@ -206,18 +205,19 @@ func (t *dialTask) String() string {
func (t *discoverTask) Do(srv *Server) { func (t *discoverTask) Do(srv *Server) {
if t.bootstrap { if t.bootstrap {
srv.ntab.Bootstrap(srv.BootstrapNodes) srv.ntab.Bootstrap(srv.BootstrapNodes)
} else { return
}
// newTasks generates a lookup task whenever dynamic dials are
// necessary. Lookups need to take some time, otherwise the
// event loop spins too fast.
next := srv.lastLookup.Add(lookupInterval)
if now := time.Now(); now.Before(next) {
time.Sleep(next.Sub(now))
}
srv.lastLookup = time.Now()
var target discover.NodeID var target discover.NodeID
rand.Read(target[:]) rand.Read(target[:])
t.results = srv.ntab.Lookup(target) t.results = srv.ntab.Lookup(target)
// newTasks generates a lookup task whenever dynamic dials are
// necessary. Lookups need to take some time, otherwise the
// event loop spins too fast. An empty result can only be
// returned if the table is empty.
if len(t.results) == 0 {
time.Sleep(emptyLookupDelay)
}
}
} }
func (t *discoverTask) String() (s string) { func (t *discoverTask) String() (s string) {

View File

@ -115,6 +115,7 @@ type Server struct {
ntab discoverTable ntab discoverTable
listener net.Listener listener net.Listener
ourHandshake *protoHandshake ourHandshake *protoHandshake
lastLookup time.Time
// These are for Peers, PeerCount (and nothing else). // These are for Peers, PeerCount (and nothing else).
peerOp chan peerOpFunc peerOp chan peerOpFunc