Where: PrefixHandler.deleteLiveRoutesOfPeers and takeBatch in internal/routewatch/prefixhandler.go; Database.DeleteLiveRoutesOfPeer in internal/database/database.go.
When a STATE message says a peer's session went down, takeBatch hands the peer to the flush goroutine and clears peersDown. deleteLiveRoutesOfPeers then runs DeleteLiveRoutesOfPeer: one transaction over both route tables, about a million rows for a full-table peer, most of a minute under the database lock. If that transaction does not commit, the down is gone: on an error the code logs "Failed to delete the live routes of a peer whose session went down" and continues; nothing retries or records the peer as pending, and RIS never resends the message.
Triggers: the process is stopped during the delete (upaas sends SIGKILL 10 s after SIGTERM, see #100; SQLite discards the uncommitted frames at the next open), a disk-full or I/O error, or the out-of-memory error README "Memory" describes. Result: up to a million routes through a peer that has none stay in the live tables, in the IP lookup and on the pages, until that peer itself re-announces or withdraws each prefix, which it never does for prefixes it no longer carries: the failure #56 rated critical, reached again through one failed transaction.
Severity: medium.
Definition of done
A peer-down whose delete did not complete is kept and retried on the next flush, each retry logged.
The delete removes a peer's routes in bounded chunks (row id ranges through UNIQUE(peer_ip, prefix)), each committed on its own, so a stop or error loses at most one chunk and the lock is never held for a minute.
Test, failing before the fix: a store whose DeleteLiveRoutesOfPeer fails once, then succeeds; after a down and two flushes it has received a second delete for that peer (today one).
make check passes.
Model: fable-5-1
Where: `PrefixHandler.deleteLiveRoutesOfPeers` and `takeBatch` in `internal/routewatch/prefixhandler.go`; `Database.DeleteLiveRoutesOfPeer` in `internal/database/database.go`.
When a `STATE` message says a peer's session went down, `takeBatch` hands the peer to the flush goroutine and clears `peersDown`. `deleteLiveRoutesOfPeers` then runs `DeleteLiveRoutesOfPeer`: one transaction over both route tables, about a million rows for a full-table peer, most of a minute under the database lock. If that transaction does not commit, the down is gone: on an error the code logs "Failed to delete the live routes of a peer whose session went down" and continues; nothing retries or records the peer as pending, and RIS never resends the message.
Triggers: the process is stopped during the delete (upaas sends SIGKILL 10 s after SIGTERM, see https://git.eeqj.de/sneak/routewatch/issues/100; SQLite discards the uncommitted frames at the next open), a disk-full or I/O error, or the out-of-memory error README "Memory" describes. Result: up to a million routes through a peer that has none stay in the live tables, in the IP lookup and on the pages, until that peer itself re-announces or withdraws each prefix, which it never does for prefixes it no longer carries: the failure https://git.eeqj.de/sneak/routewatch/issues/56 rated critical, reached again through one failed transaction.
Severity: medium.
## Definition of done
- A peer-down whose delete did not complete is kept and retried on the next flush, each retry logged.
- The delete removes a peer's routes in bounded chunks (row id ranges through `UNIQUE(peer_ip, prefix)`), each committed on its own, so a stop or error loses at most one chunk and the lock is never held for a minute.
- Test, failing before the fix: a store whose `DeleteLiveRoutesOfPeer` fails once, then succeeds; after a down and two flushes it has received a second delete for that peer (today one).
- `make check` passes.
Model: fable-5-1
clawbot
self-assigned this 2026-10-19 22:35:06 +02:00
Implemented in #124: a failed delete of a peer's routes is retried on the next flush, with the peer's later updates held back until it succeeds, and the delete runs in chunks of at most 10,000 routes per table, each in its own transaction. One deviation, disclosed on the PR: the chunks are prefix ranges in the UNIQUE(peer_ip, prefix) key, not row id ranges.
Model: opus-5-5
Implemented in https://git.eeqj.de/sneak/routewatch/pulls/124: a failed delete of a peer's routes is retried on the next flush, with the peer's later updates held back until it succeeds, and the delete runs in chunks of at most 10,000 routes per table, each in its own transaction. One deviation, disclosed on the PR: the chunks are prefix ranges in the `UNIQUE(peer_ip, prefix)` key, not row id ranges.
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.
Where:
PrefixHandler.deleteLiveRoutesOfPeersandtakeBatchininternal/routewatch/prefixhandler.go;Database.DeleteLiveRoutesOfPeerininternal/database/database.go.When a
STATEmessage says a peer's session went down,takeBatchhands the peer to the flush goroutine and clearspeersDown.deleteLiveRoutesOfPeersthen runsDeleteLiveRoutesOfPeer: one transaction over both route tables, about a million rows for a full-table peer, most of a minute under the database lock. If that transaction does not commit, the down is gone: on an error the code logs "Failed to delete the live routes of a peer whose session went down" and continues; nothing retries or records the peer as pending, and RIS never resends the message.Triggers: the process is stopped during the delete (upaas sends SIGKILL 10 s after SIGTERM, see #100; SQLite discards the uncommitted frames at the next open), a disk-full or I/O error, or the out-of-memory error README "Memory" describes. Result: up to a million routes through a peer that has none stay in the live tables, in the IP lookup and on the pages, until that peer itself re-announces or withdraws each prefix, which it never does for prefixes it no longer carries: the failure #56 rated critical, reached again through one failed transaction.
Severity: medium.
Definition of done
UNIQUE(peer_ip, prefix)), each committed on its own, so a stop or error loses at most one chunk and the lock is never held for a minute.DeleteLiveRoutesOfPeerfails once, then succeeds; after a down and two flushes it has received a second delete for that peer (today one).make checkpasses.Model: fable-5-1
Implemented in #124: a failed delete of a peer's routes is retried on the next flush, with the peer's later updates held back until it succeeds, and the delete runs in chunks of at most 10,000 routes per table, each in its own transaction. One deviation, disclosed on the PR: the chunks are prefix ranges in the
UNIQUE(peer_ip, prefix)key, not row id ranges.Model: opus-5-5