5
0
mirror of https://github.com/cwinfo/yggdrasil-go.git synced 2024-11-25 06:01:35 +00:00

adjust how dht throttle works, it should now back off faster, and back off even more if things are not in use

This commit is contained in:
Arceliar 2018-12-20 20:16:51 -06:00
parent dfcdafa55c
commit f59852b1e1

View File

@ -12,7 +12,12 @@ import (
"github.com/yggdrasil-network/yggdrasil-go/src/crypto" "github.com/yggdrasil-network/yggdrasil-go/src/crypto"
) )
const dht_lookup_size = 16 const (
dht_lookup_size = 16
dht_timeout = 6 * time.Minute
dht_max_delay = 5 * time.Minute
dht_max_delay_dirty = 30 * time.Second
)
// dhtInfo represents everything we know about a node in the DHT. // dhtInfo represents everything we know about a node in the DHT.
// This includes its key, a cache of it's NodeID, coords, and timing/ping related info for deciding who/when to ping nodes for maintenance. // This includes its key, a cache of it's NodeID, coords, and timing/ping related info for deciding who/when to ping nodes for maintenance.
@ -23,6 +28,7 @@ type dhtInfo struct {
recv time.Time // When we last received a message recv time.Time // When we last received a message
pings int // Time out if at least 3 consecutive maintenance pings drop pings int // Time out if at least 3 consecutive maintenance pings drop
throttle time.Duration throttle time.Duration
dirty bool // Set to true if we've used this node in ping responses (for queries about someone other than the person doing the asking, i.e. real searches) since the last time we heard from the node
} }
// Returns the *NodeID associated with dhtInfo.key, calculating it on the fly the first time or from a cache all subsequent times. // Returns the *NodeID associated with dhtInfo.key, calculating it on the fly the first time or from a cache all subsequent times.
@ -137,7 +143,7 @@ func (t *dht) insert(info *dhtInfo) {
// Insert a peer into the table if it hasn't been pinged lately, to keep peers from dropping // Insert a peer into the table if it hasn't been pinged lately, to keep peers from dropping
func (t *dht) insertPeer(info *dhtInfo) { func (t *dht) insertPeer(info *dhtInfo) {
oldInfo, isIn := t.table[*info.getNodeID()] oldInfo, isIn := t.table[*info.getNodeID()]
if !isIn || time.Since(oldInfo.recv) > 45*time.Second { if !isIn || time.Since(oldInfo.recv) > dht_max_delay+30*time.Second {
// TODO? also check coords? // TODO? also check coords?
t.insert(info) t.insert(info)
} }
@ -194,6 +200,14 @@ func (t *dht) handleReq(req *dhtReq) {
if _, isIn := t.table[*info.getNodeID()]; !isIn && t.isImportant(&info) { if _, isIn := t.table[*info.getNodeID()]; !isIn && t.isImportant(&info) {
t.ping(&info, nil) t.ping(&info, nil)
} }
// Maybe mark nodes from lookup as dirty
if req.Dest != *info.getNodeID() {
// This node asked about someone other than themself, so this wasn't just idle traffic.
for _, info := range res.Infos {
// Mark nodes dirty so we're sure to check up on them again later
info.dirty = true
}
}
} }
// Sends a lookup response to the specified node. // Sends a lookup response to the specified node.
@ -311,19 +325,24 @@ func (t *dht) doMaintenance() {
} }
t.callbacks = newCallbacks t.callbacks = newCallbacks
for infoID, info := range t.table { for infoID, info := range t.table {
if now.Sub(info.recv) > time.Minute || info.pings > 3 { if now.Sub(info.recv) > dht_timeout || info.pings > 6 {
delete(t.table, infoID) delete(t.table, infoID)
t.imp = nil t.imp = nil
} }
} }
for _, info := range t.getImportant() { for _, info := range t.getImportant() {
if now.Sub(info.recv) > info.throttle { switch {
case now.Sub(info.recv) > info.throttle:
info.throttle *= 2
if info.throttle < time.Second {
info.throttle = time.Second
} else if info.throttle > dht_max_delay {
info.throttle = dht_max_delay
}
fallthrough
case info.dirty && now.Sub(info.recv) > dht_max_delay_dirty:
t.ping(info, nil) t.ping(info, nil)
info.pings++ info.pings++
info.throttle += time.Second
if info.throttle > 30*time.Second {
info.throttle = 30 * time.Second
}
} }
} }
} }