check / check (push) Failing after 15m27s
Stop now counts the origin changes inside a running write, in a new writingOriginChanges field, and adds them to the count it logs. The prune test checks which rows survive, including a prefix with rows on both sides of 72 hours. The prefix page tests cover 5,000 and 5,001 rows and a row's time and peer count. New tests cover the dropped-rows warning and the dropped count's reset. The prune floor is named minOriginChangesPerPrefix. The README, TODO, package doc and doc comments are corrected to match. Model: deepseek-v4-pro
92 lines
3.1 KiB
Go
92 lines
3.1 KiB
Go
// Package database provides SQLite storage for BGP routing data: ASNs,
|
|
// prefixes, announcements, peerings, BGP peers and origin changes. Its routes
|
|
// table holds a copy of the whole routing table that internal/routetable
|
|
// keeps in memory.
|
|
package database
|
|
|
|
import (
|
|
"context"
|
|
"net/netip"
|
|
"time"
|
|
|
|
"git.eeqj.de/sneak/routewatch/internal/routetable"
|
|
)
|
|
|
|
// Stats contains database statistics: counts of ASNs, prefixes, peerings and
|
|
// peers, and the file size.
|
|
type Stats struct {
|
|
ASNs int
|
|
Prefixes int
|
|
IPv4Prefixes int
|
|
IPv6Prefixes int
|
|
Peerings int
|
|
Peers int
|
|
FileSizeBytes int64
|
|
}
|
|
|
|
// Store defines the interface for database operations. It provides methods for
|
|
// managing ASNs, prefixes, announcements, peerings, BGP peers, and the copy of
|
|
// the routing table. Implementations must be safe for concurrent use.
|
|
//
|
|
//nolint:interfacebloat // the one seam handlers and tests depend on
|
|
type Store interface {
|
|
// ASN operations
|
|
GetOrCreateASN(number int, timestamp time.Time) (*ASN, error)
|
|
GetOrCreateASNBatch(asns map[int]SeenTimes) error
|
|
|
|
// Prefix operations
|
|
GetOrCreatePrefix(prefix string, timestamp time.Time) (*Prefix, error)
|
|
UpdatePrefixesBatch(prefixes map[string]time.Time) error
|
|
|
|
// Announcement operations
|
|
RecordAnnouncement(announcement *Announcement) error
|
|
|
|
// Peering operations
|
|
RecordPeering(asA, asB int, seen SeenTimes) error
|
|
|
|
// Statistics
|
|
GetStats() (Stats, error)
|
|
GetStatsContext(ctx context.Context) (Stats, error)
|
|
|
|
// Peer operations
|
|
UpdatePeer(peerIP string, peerASN int, messageType string, timestamp time.Time) error
|
|
UpdatePeerBatch(peers map[string]PeerUpdate) error
|
|
|
|
// Routing table operations: the database's copy of the table in memory
|
|
WriteRouteChanges(changes []routetable.Change, newPeers map[string]uint) error
|
|
ReadRouteTable(ctx context.Context) (*routetable.Table, error)
|
|
|
|
// Origin change operations: the prefix and origin AS pairs' first and
|
|
// last peers, as the routing table records them.
|
|
WriteOriginChanges(changes []routetable.OriginChange) error
|
|
GetOriginChanges(
|
|
ctx context.Context, prefix netip.Prefix, limit int,
|
|
) ([]routetable.OriginChange, error)
|
|
PruneOriginChanges(ctx context.Context) error
|
|
|
|
// ASN WHOIS operations
|
|
GetNextStaleASN(ctx context.Context, staleThreshold time.Duration) (int, error)
|
|
UpdateASNWHOIS(ctx context.Context, update *ASNWHOISUpdate) error
|
|
GetWHOISStats(ctx context.Context, staleThreshold time.Duration) (*WHOISStats, error)
|
|
|
|
// AS and prefix detail operations
|
|
GetAS(ctx context.Context, asn int) (*ASN, bool, error)
|
|
GetLastSeenASes(ctx context.Context) (*ASN, *ASN, error)
|
|
GetASWHOIS(ctx context.Context, asn int) (*ASN, error)
|
|
GetPrefixFirstSeen(ctx context.Context, prefix netip.Prefix) (time.Time, error)
|
|
GetASPeers(asn int) ([]ASPeer, error)
|
|
GetASPeersContext(ctx context.Context, asn int) ([]ASPeer, error)
|
|
|
|
// Lifecycle
|
|
Close() error
|
|
|
|
// Maintenance operations
|
|
Vacuum(ctx context.Context) error
|
|
Analyze(ctx context.Context) error
|
|
Checkpoint(ctx context.Context) error
|
|
Ping(ctx context.Context) error
|
|
}
|
|
|
|
// Ensure Database implements Store
|
|
var _ Store = (*Database)(nil)
|