The prefix handler keeps only one update per prefix from each batch, across all peers, so most peers' announcements and withdrawals are thrown away without being counted.
Where: internal/routewatch/prefixhandler.go, flushBatchLocked: prefixMap is keyed by update.prefix alone and keeps the update with the later timestamp.
One routing change usually reaches many RIS peers within the same second, so a batch (up to a second of the feed, up to 25,000 updates) often holds the same prefix from dozens of peers. Only one of them is written. The others are lost: a lost withdrawal leaves that peer's route in the table for good; a lost announcement leaves the route missing or with an old AS path.
The timestamp is cut to whole seconds (ParsedTimestamp in streamer.go), and an equal timestamp does not replace the entry, so for updates in the same second the first one wins. A peer that announces and then withdraws a prefix within one second keeps the route; one that withdraws and re-announces loses it.
Failure scenario: a prefix that 40 RIS peers carry is withdrawn everywhere; the withdrawals arrive within one second and land in one batch; 39 of the 40 routes stay in live_routes_v4 and keep showing on /prefix/... and in IP lookups.
Severity: critical
Definition of done
A batch keeps the last update per prefix and peer, in the order the feed delivered them (arrival order, not timestamp comparison). Updates for the same prefix from different peers are all applied.
Tests that fail before the fix: two peers announce the same prefix in one batch and two live routes result; one peer announces and then withdraws a prefix in the same second and no route results; one peer withdraws and then re-announces and the route is present.
The in-memory counts and prefix distribution stay exact in these tests.
make check passes.
Model: opus-5-5
The prefix handler keeps only one update per prefix from each batch, across all peers, so most peers' announcements and withdrawals are thrown away without being counted.
Where: `internal/routewatch/prefixhandler.go`, `flushBatchLocked`: `prefixMap` is keyed by `update.prefix` alone and keeps the update with the later `timestamp`.
- One routing change usually reaches many RIS peers within the same second, so a batch (up to a second of the feed, up to 25,000 updates) often holds the same prefix from dozens of peers. Only one of them is written. The others are lost: a lost withdrawal leaves that peer's route in the table for good; a lost announcement leaves the route missing or with an old AS path.
- The timestamp is cut to whole seconds (`ParsedTimestamp` in `streamer.go`), and an equal timestamp does not replace the entry, so for updates in the same second the first one wins. A peer that announces and then withdraws a prefix within one second keeps the route; one that withdraws and re-announces loses it.
Failure scenario: a prefix that 40 RIS peers carry is withdrawn everywhere; the withdrawals arrive within one second and land in one batch; 39 of the 40 routes stay in `live_routes_v4` and keep showing on `/prefix/...` and in IP lookups.
Severity: critical
## Definition of done
- A batch keeps the last update per prefix and peer, in the order the feed delivered them (arrival order, not timestamp comparison). Updates for the same prefix from different peers are all applied.
- Tests that fail before the fix: two peers announce the same prefix in one batch and two live routes result; one peer announces and then withdraws a prefix in the same second and no route results; one peer withdraws and then re-announces and the route is present.
- The in-memory counts and prefix distribution stay exact in these tests.
- `make check` passes.
Model: opus-5-5
clawbot
self-assigned this 2026-10-14 14:33:43 +02:00
Fixed in #58: a batch now keeps the last update per prefix and peer, in the order the feed delivered them, so every peer's announcements and withdrawals are applied. The tests the definition of done asks for are in the PR, plus two peers withdrawing the same prefix in one batch.
Model: opus-5-5
Fixed in https://git.eeqj.de/sneak/routewatch/pulls/58: a batch now keeps the last update per prefix and peer, in the order the feed delivered them, so every peer's announcements and withdrawals are applied. The tests the definition of done asks for are in the PR, plus two peers withdrawing the same prefix in one batch.
Model: opus-5-5
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
The prefix handler keeps only one update per prefix from each batch, across all peers, so most peers' announcements and withdrawals are thrown away without being counted.
Where:
internal/routewatch/prefixhandler.go,flushBatchLocked:prefixMapis keyed byupdate.prefixalone and keeps the update with the latertimestamp.ParsedTimestampinstreamer.go), and an equal timestamp does not replace the entry, so for updates in the same second the first one wins. A peer that announces and then withdraws a prefix within one second keeps the route; one that withdraws and re-announces loses it.Failure scenario: a prefix that 40 RIS peers carry is withdrawn everywhere; the withdrawals arrive within one second and land in one batch; 39 of the 40 routes stay in
live_routes_v4and keep showing on/prefix/...and in IP lookups.Severity: critical
Definition of done
make checkpasses.Model: opus-5-5
Fixed in #58: a batch now keeps the last update per prefix and peer, in the order the feed delivered them, so every peer's announcements and withdrawals are applied. The tests the definition of done asks for are in the PR, plus two peers withdrawing the same prefix in one batch.
Model: opus-5-5