Skip to content

Sweep at boot, and stop rendering swept captures - #46

Merged
botre merged 1 commit into
masterfrom
fix/retention-sweep-at-boot
Aug 9, 2026
Merged

Sweep at boot, and stop rendering swept captures#46
botre merged 1 commit into
masterfrom
fix/retention-sweep-at-boot

Conversation

@botre

@botre botre commented Aug 9, 2026

Copy link
Copy Markdown
Collaborator

Captured requests are deleted after 4 hours. That window is stated on the landing page, on every endpoint page, and in the endpoint page description. Two things let reality drift from it.

The sweep never ran at boot

startRetentionSweep registered */5 * * * * with cron and nothing else. Cron's first tick is a full interval away, so a process restarted more often than every 5 minutes never swept at all. Deploys, crash loops, or a platform that recycles the container left captures alive past the window for as long as the database file survived.

The sweep body is now a named sweepRetention, called once before the scheduler starts.

Also corrected the doc comment on startRetentionSweep, which claimed to return "the stopped-on-exit scheduler so the caller owns its lifetime" while main() discards the return value and no shutdown path calls Stop().

An open page kept rendering captures the server had deleted

The client only mutated its list on fetch, socket append, or explicit delete, never on age. The endpoint page is built to sit open for hours, so a row reading "6 hours ago" ended up on screen directly under the line promising deletion after 4 hours.

The store gains pruneExpired, driven from the TICK_MS interval the component already runs for relative timestamps, so no second timer. Dropping rows locally is only the immediate half: the list is windowed, so it then calls the existing fetchRequests() to resync total and promote any older-but-live capture into the window.

The window reaches the page as data-retention-seconds, rendered by renderEndpoint from the same constant the sweep uses, so there is no fourth hardcoded copy of "4 hours". A page served without the attribute skips pruning rather than expiring against a guess.

Verification

  • go vet ./src/..., go test ./src/..., npm run lint, prettier --check, and the npm run css staleness check all pass locally.
  • New TestSweepRetention covers both directions; new TestPageRoutes case asserts data-retention-seconds="14400".
  • Boot sweep run against a real database: deleted old requests count=103 logged at startup, before the listener came up.
  • Client prune driven in a real browser: deleted captures server-side to simulate a sweep, confirmed the page still rendered 3 phantom rows, aged them past the window, and let the natural 30s tick fire. Rows went 3 to 0, total resynced, no console errors. A fresh capture then survived two further ticks.

The e2e suite is not extended here. A Playwright test using page.clock.fastForward would guard the client prune, and can follow.

🤖 Generated with Claude Code

https://claude.ai/code/session_01XkbFE6pgcxRfsMAvnwyuqS

The 4 hour retention window is stated on the landing page and on every
endpoint page. Two things let reality drift from it.

Cron's first tick is a full interval away, so a process restarted more
often than every 5 minutes never swept at all and captures outlived the
window for as long as the database file did. The sweep now also runs once
at startup.

An open endpoint page never expired anything from its own list, so a page
left open past the window kept rendering captures the server had already
deleted, directly under the line promising they were gone. The page now
drops them on the interval it already runs for relative timestamps, then
refetches so the total and the windowed list come from the server again.

The window reaches the page as data-retention-seconds, rendered from the
same constant the sweep uses, rather than as a fourth hardcoded copy of
the figure.

Claude-Session: https://claude.ai/code/session_01XkbFE6pgcxRfsMAvnwyuqS
@botre
botre merged commit 4933dcb into master Aug 9, 2026
4 checks passed
@botre
botre deleted the fix/retention-sweep-at-boot branch August 9, 2026 07:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant