forked from cerc-io/plugeth
p2p: throttle all discovery lookups
Lookup calls would spin out of control when network connectivity was lost. The throttling that was in place only took effect when the table returned zero results, which doesn't happen very often. The new throttling should not have a negative impact when the host is online. Lookups against the network take some time and dials for all results must complete or hit the cache before a new one is started. This usually takes longer than four seconds, leaving online lookups unaffected. Fixes #1296
This commit is contained in:
parent
3deded28a5
commit
6fb810adaa
30
p2p/dial.go
30
p2p/dial.go
@ -17,10 +17,9 @@ const (
|
||||
// redialing a certain node.
|
||||
dialHistoryExpiration = 30 * time.Second
|
||||
|
||||
// Discovery lookup tasks will wait for this long when
|
||||
// no results are returned. This can happen if the table
|
||||
// becomes empty (i.e. not often).
|
||||
emptyLookupDelay = 10 * time.Second
|
||||
// Discovery lookups are throttled and can only run
|
||||
// once every few seconds.
|
||||
lookupInterval = 4 * time.Second
|
||||
)
|
||||
|
||||
// dialstate schedules dials and discovery lookups.
|
||||
@ -206,18 +205,19 @@ func (t *dialTask) String() string {
|
||||
func (t *discoverTask) Do(srv *Server) {
|
||||
if t.bootstrap {
|
||||
srv.ntab.Bootstrap(srv.BootstrapNodes)
|
||||
} else {
|
||||
var target discover.NodeID
|
||||
rand.Read(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)
|
||||
}
|
||||
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
|
||||
rand.Read(target[:])
|
||||
t.results = srv.ntab.Lookup(target)
|
||||
}
|
||||
|
||||
func (t *discoverTask) String() (s string) {
|
||||
|
@ -115,6 +115,7 @@ type Server struct {
|
||||
ntab discoverTable
|
||||
listener net.Listener
|
||||
ourHandshake *protoHandshake
|
||||
lastLookup time.Time
|
||||
|
||||
// These are for Peers, PeerCount (and nothing else).
|
||||
peerOp chan peerOpFunc
|
||||
|
Loading…
Reference in New Issue
Block a user