mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-02-26 15:47:21 +00:00
p2p/discover: remove hot-spin in table refresh trigger (#32912)
This fixes a regression introduced in #32518. In that PR, we removed the slowdown logic that would throttle lookups when the table runs empty. Said logic was originally added in #20389. Usually it's fine, but there exist pathological cases, such as hive tests, where the node can only discover one other node, so it can only ever query that node and won't get any results. In cases like these, we need to throttle the creation of lookups to avoid crazy CPU usage.
This commit is contained in:
parent
40505a9bc0
commit
7c107c2691
1 changed files with 23 additions and 0 deletions
|
|
@ -153,6 +153,7 @@ type lookupIterator struct {
|
|||
cancel func()
|
||||
lookup *lookup
|
||||
tabRefreshing <-chan struct{}
|
||||
lastLookup time.Time
|
||||
}
|
||||
|
||||
type lookupFunc func(ctx context.Context) *lookup
|
||||
|
|
@ -185,6 +186,9 @@ func (it *lookupIterator) Next() bool {
|
|||
return false
|
||||
}
|
||||
if it.lookup == nil {
|
||||
// Ensure enough time has passed between lookup creations.
|
||||
it.slowdown()
|
||||
|
||||
it.lookup = it.nextLookup(it.ctx)
|
||||
if it.lookup.empty() {
|
||||
// If the lookup is empty right after creation, it means the local table
|
||||
|
|
@ -235,6 +239,25 @@ func (it *lookupIterator) lookupFailed(tab *Table, timeout time.Duration) {
|
|||
tab.waitForNodes(tout, 1)
|
||||
}
|
||||
|
||||
// slowdown applies a delay between creating lookups. This exists to prevent hot-spinning
|
||||
// in some test environments where lookups don't yield any results.
|
||||
func (it *lookupIterator) slowdown() {
|
||||
const minInterval = 1 * time.Second
|
||||
|
||||
now := time.Now()
|
||||
diff := now.Sub(it.lastLookup)
|
||||
it.lastLookup = now
|
||||
if diff > minInterval {
|
||||
return
|
||||
}
|
||||
wait := time.NewTimer(diff)
|
||||
defer wait.Stop()
|
||||
select {
|
||||
case <-wait.C:
|
||||
case <-it.ctx.Done():
|
||||
}
|
||||
}
|
||||
|
||||
// Close ends the iterator.
|
||||
func (it *lookupIterator) Close() {
|
||||
it.cancel()
|
||||
|
|
|
|||
Loading…
Reference in a new issue