aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFelix Lange <fjl@twurst.com>2015-06-22 06:01:56 +0800
committerFelix Lange <fjl@twurst.com>2015-06-22 07:07:58 +0800
commit6fb810adaa539a2fa97cf4481588b339ab5279ae (patch)
treefb5f5809b2641a06cbc4caba22f37687b26730b8
parent3deded28a50398b8ce108c72f27ea861c1bce178 (diff)
downloadgo-tangerine-6fb810adaa539a2fa97cf4481588b339ab5279ae.tar
go-tangerine-6fb810adaa539a2fa97cf4481588b339ab5279ae.tar.gz
go-tangerine-6fb810adaa539a2fa97cf4481588b339ab5279ae.tar.bz2
go-tangerine-6fb810adaa539a2fa97cf4481588b339ab5279ae.tar.lz
go-tangerine-6fb810adaa539a2fa97cf4481588b339ab5279ae.tar.xz
go-tangerine-6fb810adaa539a2fa97cf4481588b339ab5279ae.tar.zst
go-tangerine-6fb810adaa539a2fa97cf4481588b339ab5279ae.zip
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
-rw-r--r--p2p/dial.go30
-rw-r--r--p2p/server.go1
2 files changed, 16 insertions, 15 deletions
diff --git a/p2p/dial.go b/p2p/dial.go
index 71065c5ee..b82d6d1f5 100644
--- a/p2p/dial.go
+++ b/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) {
diff --git a/p2p/server.go b/p2p/server.go
index 59b97a0aa..5eff70345 100644
--- a/p2p/server.go
+++ b/p2p/server.go
@@ -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