Remove blah2's built-in tracker - #69
Merged
Merged
Conversation
blah2's own tracker has never been part of the product. Tracking is done by the retina-tracker sidecar, which blah2-api feeds detections over network.tracker_forward and which runs its own association. Nothing consumed blah2's tracker output: retina-gui's Tracker page proxies retina-tracker's SSE feed, and the only reference to blah2-api's /api/tracker anywhere was a debug link in web/html/controller's collapsed API section. Leaving it in was not free. Track::remove() erased six of its seven parallel per-track vectors and missed nInactive, so one uint64_t leaked per track ever created, and Tracker::process() then deep copied the whole Track every CPI. On fairforest-b that took the tracker stage from 0.19 ms at 4,472 CPIs to 30-43 ms at 558,381, and the process from 285 MB to 510 MB RSS over 77 h. Nodes have no swap, so a 2 GB board exhausts memory in roughly a fortnight of uptime. The desynchronised nInactive also silently corrupted the deletion logic, which is gated on get_nInactive(i) > nDelete. It was a standing source of confusion too: four interacting defects in Tracker::update meant it never associated anything, so /api/tracker always returned an empty data array, which people kept rediscovering. Removes the sources, both CMake targets, the /api/tracker endpoint and its port-3003 listener, the tracker keys from the repo configs, and the comments that explained the pipeline ordering in terms of the tracker's state. Detection output and the retina-tracker feed are untouched. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Author
|
Pairs with offworldlabs/retina-node#40, which makes the config change reach deployed nodes. Deploy |
Purple10101
added a commit
that referenced
this pull request
Sep 23, 2026
/api/tracker went out in #69, but the api tag description still listed "tracks" among what the tag covers, so the reference advertised a route that no longer exists. openapi:check cannot catch this: the tag text is hand-written and lands identically on both sides of the comparison, so it stays green while the prose goes stale. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Removes blah2's built-in tracker outright:
Track,Tracker, their tests, thetracksocket and port,/api/trackerand its TCP listener, and the configkeys. -1104 lines.
It leaked, and nothing consumed it.
Why remove rather than fix
Track::remove()erased six of its seven parallel per-track vectors and missednInactive, whichadd()pushes for every track created.Tracker::processthen returned
std::make_unique<Track>(track)— a deep copy of the whole Track,every CPI — so that ever-growing vector was allocated, copied and freed twice
a second with more than one instance resident at peak.
Measured on fairforest-b over a 50 minute window at ~78 h uptime: 100% of RSS
growth landed in exactly those two mappings, at 2.00 MB/h. No other mapping
moved. On a 2 GB board with no swap and ~870 MB free, that is 18 days to
exhaustion.
Reproduced offline against pristine
origin/main(realTracker/Track,synthetic detections, 20,000 CPIs = 2.78 simulated hours):
idholds correct steady state at 30.nInactiveclimbs linearly to 300,000.Fixing the missing erase alone was viable, but nothing reads this tracker:
/api/trackerwas the only reader of the track socket, and theonly reference to that endpoint anywhere was a debug link in a collapsed
section of
web/html/controller/index.html.the origin (
delayPredict/dopplerPredictare initialised to 0.0 and neverassigned from the prediction), so with
minDelay: 5nothing can everassociate and
Track::to_jsonomits tentative tracks./api/trackerhasalways returned
data: [].Live verification on owl-ded9
Deployed with the matching retina-node change (see below) and left overnight.
NumDevs=1, normal startuptrackerkey in/api/timing/api/trackerMemory over 12.84 h and 86,919 CPIs:
After warm-up: +1.98 MB over 11.87 h = 0.167 MB/h, a 12x reduction on
the 2.00 MB/h it replaces. The character changed too: the old leak moved on
every sample, this is a flat line with three isolated steps whose gaps are
doubling (1 h, 3 h, 6.25 h) — the signature of a geometrically-growing
structure rather than linear accumulation.
VmHWM == VmRSSat the end, sonothing transient is hiding above it.
Runway on a 2 GB board goes from 18 days to roughly 7 months.
Deployment: three images move together
blah2,blah2-apiandconfig-mergermust be deployed as a set.The matching retina-node change strips
process.trackerandnetwork.ports.trackfrom the merged config. Against that config:process.tracker.enablethrough ryml, whose defaulterror handler calls
abort()— it dies rather than warns;server_tracker.listen(config.network.ports.track)with the key gone, so it binds a random free port, silently.
The second one is easy to miss: during verification
/api/trackerkeptanswering 200 after the config was stripped, purely because the API had not
restarted and was still holding its original bind on 3003.
Recreating
blah2-apialso takes blah2 down with it (exit 0,Error sending data: Broken pipe, recovers). Pre-existing and unrelated to this change, but itmeans the rollout costs a brief blah2 restart.
Not addressed here
The association bug that makes the tracker useless is moot now, but the same
defects exist in the retina-tracker sidecar's lineage if it was ported from
this code — worth a look separately.
🤖 Generated with Claude Code