1 Commits
Author SHA1 Message Date
sneak feecdb0ca3 Let the lock go for as long as it was held during Overview's walk (closes #226)
check / check (push) Canceled after 0s
The home page's cards are worked out once a minute by Overview, which
walks every prefix of the routing table under its read lock. After each
batch of 10,000 prefixes it let the lock go and took it back at once.
The prefix handler, waiting for the write lock, then got in only once
per batch. Its queue filled, and the streamer dropped updates for it.

The walk now lets the lock go for as long as it held it for the batch,
as PeerDown does. A test applies another peer's 1,000 announcements
while Overview walks a table of more than five batches.

Model: opus-5-5
2026-11-02 05:51:12 +00:00
3 changed files with 9 additions and 9 deletions
+2 -2
View File
@@ -39,8 +39,8 @@ tested.
handler. The walk over the routing table holds the table's lock for 10,000
prefixes at a time, then lets the lock go for as long again, as `PeerDown`
does. It used to take the lock back at once. The prefix handler then applied
about one update per 10,000 prefixes walked. During a walk, its queue could
fill, and the streamer then dropped updates for it (closes #226)
about one update per 10,000 prefixes walked. Its queue filled, and the
streamer dropped updates for it once a minute (closes #226)
- 2026-11-02: like a failed WHOIS lookup, a lookup skipped because its RIR is
paused makes the fetcher wait longer before the next lookup. The longest wait
is one minute. The status page does not count a skip as a failure. A skip used
+3 -3
View File
@@ -114,9 +114,9 @@ func (t *Table) Overview(maxListed int) Overview {
// holds the read lock for walkBatch prefixes at a time. After each batch, it
// lets the table's lock go for as long as it held the lock for the batch.
// During a walk over many batches, updates can then take the lock about half
// of the time. The walk may or may not visit a prefix that is added or removed
// while the lock is let go. Go allows this in a range over a map that changes.
// visit must not keep origins once it returns.
// of the time. A prefix that is added or removed while the lock is let go may
// or may not be visited, as Go allows for a map that changes during a range
// over it. visit must not keep origins once it returns.
func (t *Table) walkPrefixes(visit func(prefix netip.Prefix, origins []*origin)) {
t.mu.RLock()
defer t.mu.RUnlock()
@@ -133,10 +133,10 @@ func TestWalkPrefixesLetsUpdatesIn(t *testing.T) {
}
// TestOverviewLetsUpdatesIn applies another peer's 1,000 announcements while
// Overview walks a table with more prefixes than five of the walk's batches.
// After each batch, the walk lets the lock go for as long as it held the lock.
// So all 1,000 announcements must be applied before Overview returns. A walk
// that takes the lock back at once lets in about one update per batch.
// Overview walks a table of more than five batches. After each batch, the walk
// lets the lock go for as long as it held it, so all of them must be applied
// before Overview returns. A walk that takes the lock back at once lets in
// about one update per batch.
func TestOverviewLetsUpdatesIn(t *testing.T) {
t.Parallel()