Take every down peer out of the table in one walk (closes #225)
check / check (push) Canceled after 0s

The prefix handler ran one PeerDown per peer, one after another, and
stopped taking messages at 20,000 held-back messages. Sessions going
down together queued up their walks, so a returning full-table peer
could reach that limit.

The table's PeersDown now takes several peers out of every prefix in
one walk. One walk runs at a time. The next one takes every peer whose
session went down meanwhile, so a message is held back for about two
walks at most. The limit is now 100,000 messages, about 100 MiB. The
status page shows how many messages each handler holds back.

Model: opus-5-5
This commit is contained in:
clawbot committed 2026-11-02 05:59:04 +00:00
1 parent d66c59ef07
commit 9187cd47b6
15 files changed
+398 -121

No files matched your search

@@ -7,11 +7,11 @@ import (
"time"
)
// TestPeerDownLetsReadsIn reads the table's counts again and again while a peer
// that carries more than two batches of prefixes goes down. PeerDown lets the
// lock go after every walkBatch prefixes, so a read must get in while the peer
// still carries some of its prefixes but no longer all.
func TestPeerDownLetsReadsIn(t *testing.T) {
// TestPeersDownLetsReadsIn reads the table's counts again and again while a
// peer that carries more than two batches of prefixes goes down. PeersDown lets
// the lock go after every walkBatch prefixes, so a read must get in while the
// peer still carries some of its prefixes but no longer all.
func TestPeersDownLetsReadsIn(t *testing.T) {
t.Parallel()
const (
@@ -32,8 +32,8 @@ func TestPeerDownLetsReadsIn(t *testing.T) {
addr = addr.Next()
}
// Hold a read lock until PeerDown waits for the lock, so that the first
// read below starts once PeerDown holds it. TryRLock fails once a writer
// Hold a read lock until PeersDown waits for the lock, so that the first
// read below starts once PeersDown holds it. TryRLock fails once a writer
// waits.
table.mu.RLock()
@@ -42,7 +42,7 @@ func TestPeerDownLetsReadsIn(t *testing.T) {
go func() {
defer close(peerDownDone)
table.PeerDown(peer)
table.PeersDown([]string{peer})
}()
for table.mu.TryRLock() {
@@ -60,7 +60,7 @@ func TestPeerDownLetsReadsIn(t *testing.T) {
select {
case <-peerDownDone:
t.Fatal("no read got in while PeerDown ran")
t.Fatal("no read got in while PeersDown ran")
default:
}
}