Simplify peerings table to store AS numbers directly
- Rename asn_peerings table to peerings - Change columns from from_asn_id/to_asn_id to as_a/as_b (integers) - Remove foreign key constraints to asns table - Update RecordPeering to use AS numbers directly - Add validation in RecordPeering to ensure: - Both AS numbers are > 0 - AS numbers are different - as_a is always lower than as_b (normalized) - Update PeeringHandler to no longer need ASN cache - Simplify the code by removing unnecessary ASN lookups
This commit is contained in:
@@ -2,6 +2,7 @@ package routewatch
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"strings"
|
||||
"sync"
|
||||
"testing"
|
||||
@@ -119,11 +120,16 @@ func (m *mockStore) RecordAnnouncement(_ *database.Announcement) error {
|
||||
}
|
||||
|
||||
// RecordPeering mock implementation
|
||||
func (m *mockStore) RecordPeering(fromASNID, toASNID string, _ time.Time) error {
|
||||
func (m *mockStore) RecordPeering(asA, asB int, _ time.Time) error {
|
||||
m.mu.Lock()
|
||||
defer m.mu.Unlock()
|
||||
|
||||
key := fromASNID + "_" + toASNID
|
||||
// Normalize
|
||||
if asA > asB {
|
||||
asA, asB = asB, asA
|
||||
}
|
||||
|
||||
key := fmt.Sprintf("%d_%d", asA, asB)
|
||||
if !m.Peerings[key] {
|
||||
m.Peerings[key] = true
|
||||
m.PeeringCount++
|
||||
|
||||
@@ -33,9 +33,8 @@ type PeeringHandler struct {
|
||||
logger *logger.Logger
|
||||
|
||||
// In-memory AS path tracking
|
||||
mu sync.RWMutex
|
||||
asPaths map[string]time.Time // key is JSON-encoded AS path
|
||||
asnCache map[int]*database.ASN
|
||||
mu sync.RWMutex
|
||||
asPaths map[string]time.Time // key is JSON-encoded AS path
|
||||
|
||||
stopCh chan struct{}
|
||||
}
|
||||
@@ -43,11 +42,10 @@ type PeeringHandler struct {
|
||||
// NewPeeringHandler creates a new batched peering handler
|
||||
func NewPeeringHandler(db database.Store, logger *logger.Logger) *PeeringHandler {
|
||||
h := &PeeringHandler{
|
||||
db: db,
|
||||
logger: logger,
|
||||
asPaths: make(map[string]time.Time),
|
||||
asnCache: make(map[int]*database.ASN),
|
||||
stopCh: make(chan struct{}),
|
||||
db: db,
|
||||
logger: logger,
|
||||
asPaths: make(map[string]time.Time),
|
||||
stopCh: make(chan struct{}),
|
||||
}
|
||||
|
||||
// Start the periodic processing goroutines
|
||||
@@ -167,7 +165,6 @@ func (h *PeeringHandler) processPeerings() {
|
||||
low, high int
|
||||
}
|
||||
peerings := make(map[peeringKey]time.Time)
|
||||
uniqueASNs := make(map[int]struct{})
|
||||
|
||||
for pathJSON, timestamp := range pathsCopy {
|
||||
var path []int
|
||||
@@ -182,6 +179,11 @@ func (h *PeeringHandler) processPeerings() {
|
||||
asn1 := path[i]
|
||||
asn2 := path[i+1]
|
||||
|
||||
// Skip invalid ASNs
|
||||
if asn1 <= 0 || asn2 <= 0 || asn1 == asn2 {
|
||||
continue
|
||||
}
|
||||
|
||||
// Normalize: lower AS number first
|
||||
low, high := asn1, asn2
|
||||
if low > high {
|
||||
@@ -193,22 +195,6 @@ func (h *PeeringHandler) processPeerings() {
|
||||
if existing, ok := peerings[key]; !ok || timestamp.After(existing) {
|
||||
peerings[key] = timestamp
|
||||
}
|
||||
|
||||
uniqueASNs[asn1] = struct{}{}
|
||||
uniqueASNs[asn2] = struct{}{}
|
||||
}
|
||||
}
|
||||
|
||||
// Get or create ASNs
|
||||
for asn := range uniqueASNs {
|
||||
if _, ok := h.asnCache[asn]; !ok {
|
||||
asnObj, err := h.db.GetOrCreateASN(asn, time.Now())
|
||||
if err != nil {
|
||||
h.logger.Error("Failed to get/create ASN", "asn", asn, "error", err)
|
||||
|
||||
continue
|
||||
}
|
||||
h.asnCache[asn] = asnObj
|
||||
}
|
||||
}
|
||||
|
||||
@@ -216,19 +202,15 @@ func (h *PeeringHandler) processPeerings() {
|
||||
start := time.Now()
|
||||
successCount := 0
|
||||
for key, ts := range peerings {
|
||||
fromAS := h.asnCache[key.low]
|
||||
toAS := h.asnCache[key.high]
|
||||
if fromAS != nil && toAS != nil {
|
||||
err := h.db.RecordPeering(fromAS.ID.String(), toAS.ID.String(), ts)
|
||||
if err != nil {
|
||||
h.logger.Error("Failed to record peering",
|
||||
"from_asn", key.low,
|
||||
"to_asn", key.high,
|
||||
"error", err,
|
||||
)
|
||||
} else {
|
||||
successCount++
|
||||
}
|
||||
err := h.db.RecordPeering(key.low, key.high, ts)
|
||||
if err != nil {
|
||||
h.logger.Error("Failed to record peering",
|
||||
"as_a", key.low,
|
||||
"as_b", key.high,
|
||||
"error", err,
|
||||
)
|
||||
} else {
|
||||
successCount++
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user