mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-25 06:06:44 +00:00
eth/downloader: use median RTT as the default for new peers
This commit is contained in:
parent
ad8378a8d1
commit
5255d20054
2 changed files with 24 additions and 24 deletions
|
|
@ -1878,24 +1878,8 @@ func (d *Downloader) deliver(id string, destCh chan dataPack, packet dataPack, i
|
||||||
// peer latency statistics and updates the estimated request round trip time.
|
// peer latency statistics and updates the estimated request round trip time.
|
||||||
func (d *Downloader) qosTuner() {
|
func (d *Downloader) qosTuner() {
|
||||||
for atomic.LoadInt32(&d.interrupt) == 0 {
|
for atomic.LoadInt32(&d.interrupt) == 0 {
|
||||||
// Gather all the active RTTs and set the target RTT to the median
|
// Retrieve the current median RTT and integrate into the previoust target RTT
|
||||||
rtts := d.peers.RTTs()
|
rtt := time.Duration(float64(1-qosTuningImpact)*float64(atomic.LoadUint64(&d.rttEstimate)) + qosTuningImpact*float64(d.peers.medianRTT()))
|
||||||
|
|
||||||
var rtt time.Duration
|
|
||||||
if qosTuningPeers <= len(rtts) {
|
|
||||||
rtt = rtts[qosTuningPeers/2] // Median of our tuning peers
|
|
||||||
} else if len(rtts) > 0 {
|
|
||||||
rtt = rtts[len(rtts)/2] // Median of our connected peers (maintain even like this some baseline qos)
|
|
||||||
} else {
|
|
||||||
rtt = rttMaxEstimate // No peers, reset to some sane default
|
|
||||||
}
|
|
||||||
if rtt < rttMinEstimate {
|
|
||||||
rtt = rttMinEstimate
|
|
||||||
}
|
|
||||||
if rtt > rttMaxEstimate {
|
|
||||||
rtt = rttMaxEstimate
|
|
||||||
}
|
|
||||||
rtt = time.Duration(float64(1-qosTuningImpact)*float64(atomic.LoadUint64(&d.rttEstimate)) + qosTuningImpact*float64(rtt))
|
|
||||||
atomic.StoreUint64(&d.rttEstimate, uint64(rtt))
|
atomic.StoreUint64(&d.rttEstimate, uint64(rtt))
|
||||||
|
|
||||||
// A new RTT cycle passed, increase our confidence in the estimated RTT
|
// A new RTT cycle passed, increase our confidence in the estimated RTT
|
||||||
|
|
|
||||||
|
|
@ -409,6 +409,10 @@ func (ps *peerSet) Reset() {
|
||||||
// average of all existing peers, to give it a realistic chance of being used
|
// average of all existing peers, to give it a realistic chance of being used
|
||||||
// for data retrievals.
|
// for data retrievals.
|
||||||
func (ps *peerSet) Register(p *peer) error {
|
func (ps *peerSet) Register(p *peer) error {
|
||||||
|
// Retrieve the current median RTT as a sane default
|
||||||
|
p.rtt = ps.medianRTT()
|
||||||
|
|
||||||
|
// Register the new peer with some meaningful defaults
|
||||||
ps.lock.Lock()
|
ps.lock.Lock()
|
||||||
defer ps.lock.Unlock()
|
defer ps.lock.Unlock()
|
||||||
|
|
||||||
|
|
@ -417,7 +421,6 @@ func (ps *peerSet) Register(p *peer) error {
|
||||||
}
|
}
|
||||||
if len(ps.peers) > 0 {
|
if len(ps.peers) > 0 {
|
||||||
p.headerThroughput, p.blockThroughput, p.receiptThroughput, p.stateThroughput = 0, 0, 0, 0
|
p.headerThroughput, p.blockThroughput, p.receiptThroughput, p.stateThroughput = 0, 0, 0, 0
|
||||||
p.rtt = rttMaxEstimate
|
|
||||||
|
|
||||||
for _, peer := range ps.peers {
|
for _, peer := range ps.peers {
|
||||||
peer.lock.RLock()
|
peer.lock.RLock()
|
||||||
|
|
@ -573,9 +576,9 @@ func (ps *peerSet) idlePeers(minProtocol, maxProtocol int, idleCheck func(*peer)
|
||||||
return idle, total
|
return idle, total
|
||||||
}
|
}
|
||||||
|
|
||||||
// RTTs retrieves all the round trip times measured for the current set of peers,
|
// medianRTT returns the median RTT of te peerset, considering only the tuning
|
||||||
// sorted ascending.
|
// peers if there are more peers available.
|
||||||
func (ps *peerSet) RTTs() []time.Duration {
|
func (ps *peerSet) medianRTT() time.Duration {
|
||||||
// Gather all the currnetly measured round trip times
|
// Gather all the currnetly measured round trip times
|
||||||
ps.lock.RLock()
|
ps.lock.RLock()
|
||||||
defer ps.lock.RUnlock()
|
defer ps.lock.RUnlock()
|
||||||
|
|
@ -586,7 +589,7 @@ func (ps *peerSet) RTTs() []time.Duration {
|
||||||
rtts = append(rtts, p.rtt)
|
rtts = append(rtts, p.rtt)
|
||||||
p.lock.RUnlock()
|
p.lock.RUnlock()
|
||||||
}
|
}
|
||||||
// Sort into ascending order and return them
|
// Sort into ascending order and retrieve the median
|
||||||
for i := 0; i < len(rtts); i++ {
|
for i := 0; i < len(rtts); i++ {
|
||||||
for j := i + 1; j < len(rtts); j++ {
|
for j := i + 1; j < len(rtts); j++ {
|
||||||
if rtts[i] > rtts[j] {
|
if rtts[i] > rtts[j] {
|
||||||
|
|
@ -594,5 +597,18 @@ func (ps *peerSet) RTTs() []time.Duration {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return rtts
|
median := rttMaxEstimate
|
||||||
|
if qosTuningPeers <= len(rtts) {
|
||||||
|
median = rtts[qosTuningPeers/2] // Median of our tuning peers
|
||||||
|
} else if len(rtts) > 0 {
|
||||||
|
median = rtts[len(rtts)/2] // Median of our connected peers (maintain even like this some baseline qos)
|
||||||
|
}
|
||||||
|
// Restrict the RTT into some QoS defaults, irrelevant of true RTT
|
||||||
|
if median < rttMinEstimate {
|
||||||
|
median = rttMinEstimate
|
||||||
|
}
|
||||||
|
if median > rttMaxEstimate {
|
||||||
|
median = rttMaxEstimate
|
||||||
|
}
|
||||||
|
return median
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue