Remove a peer's live routes when its session goes down (closes #56)
check / check (push) Canceled after 0s

RIS sends no withdrawals for the routes of a peer whose BGP session goes
down, so routewatch kept them.

The streamer now hands STATE messages to the prefix handler. They are never
dropped for backpressure: one that finds the queue full is held and queued
first once there is room, and the handler's other messages are dropped
meanwhile, so none overtakes it. Nothing waits. On a down, the prefix
handler drops the peer's pending updates and its next flush deletes all the
peer's live routes before the batch's other writes, keeping the in-memory
counts exact. The live route tables are unique on peer and prefix, which
also finds a peer's routes.

Model: opus-5-5
This commit was merged in pull request #88.
This commit is contained in:
2026-10-19 11:40:31 +02:00
parent a0ddc0d254
commit 825afa2ebe
12 changed files with 787 additions and 51 deletions
+7 -7
View File
@@ -1,7 +1,7 @@
package routewatch
// peerhandler.go provides batched peer tracking functionality for BGP route monitoring.
// It tracks BGP peers from all incoming RIS messages and maintains peer state in the database.
// It tracks BGP peers from incoming UPDATE messages and maintains peer state in the database.
import (
"strconv"
@@ -33,7 +33,7 @@ const (
peerBatchTimeout = 2 * time.Second
)
// PeerHandler tracks BGP peers from all message types using batched operations.
// PeerHandler tracks BGP peers from UPDATE messages using batched operations.
// It maintains a queue of peer updates and periodically flushes them to the database
// in batches to improve performance. The handler deduplicates peer updates within
// each batch, keeping only the most recent update for each peer IP address.
@@ -82,11 +82,11 @@ func NewPeerHandler(db database.Store, logger *logger.Logger) *PeerHandler {
return h
}
// WantsMessage returns true for all message types since peer information
// is extracted from every RIS message regardless of type. This satisfies
// the MessageHandler interface.
func (h *PeerHandler) WantsMessage(_ string) bool {
return true
// WantsMessage returns true for UPDATE messages only. A peer whose session
// never comes up sends STATE messages and nothing else, so a STATE message is
// not a sign of a peer that carries routes.
func (h *PeerHandler) WantsMessage(messageType string) bool {
return messageType == ristypes.MessageTypeUpdate
}
// QueueCapacity returns the desired queue capacity for this handler.