Remove the per-peer route tables (closes #122)
check / check (push) Canceled after 0s

The routing table in memory now holds every route, so the two per-peer route
tables go, with every write, delete, count and read that served them. The
prefix handler applies each update to the table, writes the table's changes
every second, and stores each new prefix with its first-seen time. The peer
delete, its retry on the next flush and the updates held for it go too. The
types and errors of the server's answers move to internal/server.

The image's memory settings fit a full table of about 1 GB: GOMEMLIMIT of
2.5 GiB, a 512 MiB page cache for the writing connection, and SQLite heap
limits of 768 MiB and 1 GiB. The README describes the new table, its
database copy and the memory budget.

Model: opus-5-5
This commit was merged in pull request #195.
This commit is contained in:
clawbot committed 2026-10-27 17:22:32 +01:00
1 parent 506e289a63
commit 1c65656b58
23 files changed
+701 -5273

No files matched your search

+15 -25
View File
@@ -81,9 +81,9 @@ func TestFlushLoopWritesOnEveryTick(t *testing.T) {
}
// blockingStore is a mockStore whose batch writes for the AS, peer and prefix
// handlers, delete of a peer's routes and peering write wait until the test
// calls releaseWrites. writeStarted is closed when the first of them starts. It
// records what each batch write was given.
// handlers and peering write wait until the test calls releaseWrites.
// writeStarted is closed when the first of them starts. It records what each
// batch write was given.
type blockingStore struct {
*mockStore
@@ -109,13 +109,13 @@ func newBlockingStore() *blockingStore {
}
}
func (s *blockingStore) UpsertLiveRouteBatch(routes []*database.LiveRoute) error {
func (s *blockingStore) UpdatePrefixesBatch(prefixes map[string]time.Time) error {
s.waitForRelease()
s.mu.Lock()
defer s.mu.Unlock()
for _, route := range routes {
s.prefixes[route.Prefix] = true
for prefix := range prefixes {
s.prefixes[prefix] = true
}
return nil
@@ -145,12 +145,6 @@ func (s *blockingStore) UpdatePeerBatch(peers map[string]database.PeerUpdate) er
return nil
}
func (s *blockingStore) DeleteLiveRoutesOfPeer(peerIP string) (int, error) {
s.waitForRelease()
return s.mockStore.DeleteLiveRoutesOfPeer(peerIP)
}
func (s *blockingStore) RecordPeering(
asA, asB int, seen database.SeenTimes,
) error {
@@ -176,7 +170,6 @@ func (s *blockingStore) releaseWrites() {
type stopLog struct {
Msg string `json:"msg"`
Updates int `json:"updates"`
PeersDown int `json:"peers_down"`
TableChanges int `json:"table_changes"`
Paths int `json:"paths"`
}
@@ -374,10 +367,10 @@ func stopWhileAWriteIsBlocked(
}
// TestPrefixHandlerSkipsItsLastWriteAfterTheStopDeadline also checks the
// routing table's changes: the flush whose delete is held wrote those of the
// fill, so Stop must log the one of the extra prefix as not written. The flush
// timer must not fire. A flush it started before the fill would be the one
// held, and it would not have written the fill's change.
// routing table's changes: the flush whose prefix write is held wrote those of
// the fill, so Stop must log the one of the extra prefix as not written. The
// flush timer must not fire. A flush it started before the fill would be the
// one held, and it would not have written the fill's change.
func TestPrefixHandlerSkipsItsLastWriteAfterTheStopDeadline(t *testing.T) {
t.Parallel()
@@ -389,10 +382,8 @@ func TestPrefixHandlerSkipsItsLastWriteAfterTheStopDeadline(t *testing.T) {
h := newPrefixHandler(store, newErrorLogger(&logs),
routetable.New(routetable.Params{}), longerThanAnyTest)
fill := slices.Repeat([]string{testV4Prefix}, prefixBatchSize)
// The peer's session goes down first, so the write held is the delete of
// its routes, and Stop must log that peer down too.
stopWhileAWriteIsBlocked(t, store, h, h.done,
[]*ristypes.RISMessage{sessionDown(), prefixAnnouncement(fill)},
[]*ristypes.RISMessage{prefixAnnouncement(fill)},
prefixAnnouncement([]string{extraPrefix}))
store.mu.Lock()
@@ -403,11 +394,10 @@ func TestPrefixHandlerSkipsItsLastWriteAfterTheStopDeadline(t *testing.T) {
}
logged := lastLogged(t, &logs)
if logged.Updates != prefixBatchSize+1 || logged.PeersDown != 1 ||
logged.TableChanges != 1 {
t.Errorf("Stop logged %d updates, %d peer downs and %d table changes "+
"not written, want %d, 1 and 1", logged.Updates, logged.PeersDown,
logged.TableChanges, prefixBatchSize+1)
if logged.Updates != prefixBatchSize+1 || logged.TableChanges != 1 {
t.Errorf("Stop logged %d updates and %d table changes not written, "+
"want %d and 1", logged.Updates, logged.TableChanges,
prefixBatchSize+1)
}
}