Skip to content

Commit 7c107c2

Browse files
authored
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.
1 parent 40505a9 commit 7c107c2

File tree

1 file changed

+23
-0
lines changed

1 file changed

+23
-0
lines changed

p2p/discover/lookup.go

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,7 @@ type lookupIterator struct {
153153
cancel func()
154154
lookup *lookup
155155
tabRefreshing <-chan struct{}
156+
lastLookup time.Time
156157
}
157158

158159
type lookupFunc func(ctx context.Context) *lookup
@@ -185,6 +186,9 @@ func (it *lookupIterator) Next() bool {
185186
return false
186187
}
187188
if it.lookup == nil {
189+
// Ensure enough time has passed between lookup creations.
190+
it.slowdown()
191+
188192
it.lookup = it.nextLookup(it.ctx)
189193
if it.lookup.empty() {
190194
// 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) {
235239
tab.waitForNodes(tout, 1)
236240
}
237241

242+
// slowdown applies a delay between creating lookups. This exists to prevent hot-spinning
243+
// in some test environments where lookups don't yield any results.
244+
func (it *lookupIterator) slowdown() {
245+
const minInterval = 1 * time.Second
246+
247+
now := time.Now()
248+
diff := now.Sub(it.lastLookup)
249+
it.lastLookup = now
250+
if diff > minInterval {
251+
return
252+
}
253+
wait := time.NewTimer(diff)
254+
defer wait.Stop()
255+
select {
256+
case <-wait.C:
257+
case <-it.ctx.Done():
258+
}
259+
}
260+
238261
// Close ends the iterator.
239262
func (it *lookupIterator) Close() {
240263
it.cancel()

0 commit comments

Comments
 (0)