Repository navigation
fix(server): free deleted sandboxes' buffers on every replica - #5460
Conversation
Delete cleanup runs only on the replica that served the delete or holds the reconciler lease, so other replicas kept a deleted sandbox's log and event buffers forever. Each multi-replica gateway now sweeps its own idle buffers every 30s, checks which sandboxes still exist with a batched primary-key lookup, and closes the ones missing on two consecutive sweeps. Buffers with live receivers or activity in the last two minutes are skipped, so the cost scales with a replica's idle local state, not fleet size or replica count. Signed-off-by: divesh <dgude@nvidia.com>
|
Reviewed commit
Reproduction results using the PR's bus and sweeper code in a standalone component harness: The harness used a deterministic missing-record store response and controlled buffer ages. It exercised the bus/sweeper logic, not a live two-gateway deployment or the complete gRPC producer. The logs-only watch's lack of deletion observation was verified by inspecting the watch handler. |
A logs-only WatchSandbox never learns of a deletion served by another replica, so skipping buffers with live receivers kept them forever and left the watch hanging. Check every quiet buffer; closing one ends its watch streams. Signed-off-by: divesh <dgude@nvidia.com>
|
@TaylorMutch , Kept the timing as a deliberate safety margin and updated #5401's criterion to "within a few minutes (about 3 with the default sweep settings)". |
|
/ok to test 921bb7e |
TaylorMutch
left a comment
There was a problem hiding this comment.
Re-reviewed commit 921bb7e. Both previous findings are addressed:
- Quiet buffers are now checked even with live receivers. Component verification confirmed a deleted sandbox's buffers are freed and its receiver closes after two sweeps, while a live watched sandbox survives 100 sweeps with its logs and receiver intact. The added WatchSandbox handler test covers termination of a logs-only watch after deletion elsewhere.
- Issue #5401 now explicitly allows about three minutes for cleanup, matching the default idle threshold and two-sweep confirmation. Component verification confirmed cleanup at a simulated 150 seconds.
Relevant Rust, lint, and PostgreSQL CI checks pass. Deployment E2E jobs were skipped; the PR author reports a successful live two-gateway retest. Local verification was component-level, using deterministic store responses and controlled buffer ages.
No remaining blocking findings.
…#5460) * fix(server): free deleted sandboxes' buffers on every replica (NVIDIA#5401) Delete cleanup runs only on the replica that served the delete or holds the reconciler lease, so other replicas kept a deleted sandbox's log and event buffers forever. Each multi-replica gateway now sweeps its own idle buffers every 30s, checks which sandboxes still exist with a batched primary-key lookup, and closes the ones missing on two consecutive sweeps. Buffers with live receivers or activity in the last two minutes are skipped, so the cost scales with a replica's idle local state, not fleet size or replica count. Signed-off-by: divesh <dgude@nvidia.com> * fix(server): sweep watched buffers of deleted sandboxes (NVIDIA#5401) A logs-only WatchSandbox never learns of a deletion served by another replica, so skipping buffers with live receivers kept them forever and left the watch hanging. Check every quiet buffer; closing one ends its watch streams. Signed-off-by: divesh <dgude@nvidia.com> --------- Signed-off-by: divesh <dgude@nvidia.com>
Summary
Related Issue
Closes #5401
Changes
bus_sweepertask, every 30s, only on multi-replica (Postgres) gateways.openshell logs --tailexits instead of hanging after a delete on another gateway.Store::existing_ids(): primary-keyIN (...)lookup in batches of 500, Postgres and SQLite.TracingLogBustracks last activity per buffer and lists idle sandboxes.Release Notes
Testing
openshell-serverfmt, clippy, and unit tests passWatchSandboxends after the sweep, store failure frees nothing,existing_idsbatchingmise run test:rust:postgres)closed=10); a live sandbox kept its logslogs --tailstayed open on the other gateway was freed ~2.5 min later and the tail exited; a live, watched sandbox kept its tail and logsChecklist