Skip to content

Zero freed slots before pooling/reslicing in clearLocked and delRequest#79

Merged
linkdata merged 2 commits into
mainfrom
fix/core-retention-clear-slots
Jun 18, 2026
Merged

Zero freed slots before pooling/reslicing in clearLocked and delRequest#79
linkdata merged 2 commits into
mainfrom
fix/core-retention-clear-slots

Conversation

@linkdata

Copy link
Copy Markdown
Owner

Defects (second-pass per-package review)

Two low-severity GC-retention nits where a freed slice slot kept a stale reference live, each inconsistent with the deliberate reference-clearing already present in the same file.

1. clearLocked pools a Request without releasing wsQueue payloads (request.go)

clearLocked reset the outbound queue with rq.wsQueue = rq.wsQueue[:0], leaving the previous wire.WsMsg values — including Data, which carries full what.Inner/Replace/Append HTML payloads — live in the backing array of a Request returned to sync.Pool. A pooled Request can sit idle indefinitely, pinning those payloads until a future reuse overwrites each slot. This is inconsistent with the adjacent clear(rq.todoDirt) and clear(rq.elems) (both commented as releasing references before pooling) and with drainTailScript, which zeroes its freed slots.

2. delRequest leaves a stale *Request in the backing array (session.go)

The swap-remove copied requests[l-1] into the found index then resliced to [:l-1], but never nilled the vacated tail slot — so the backing array retained an otherwise-recyclable *Request (the duplicated one after a swap, or the original when removing the last element) for the session's lifetime.

Fix

  • clear(rq.wsQueue) before the [:0] reslice (still under muQueue).
  • sess.requests[l-1] = nil before reslicing.

Neither is a correctness bug — all iterators use the resliced length, so the stale entries are never observed — purely retention/consistency.

Tests

slotclear_test.go (internal package jaws) asserts the freed backing-array slots are zeroed: TestClearLockedZeroesWsQueue queues messages with payloads, runs clearLocked, and checks wsQueue[:cap] is all zero; TestDelRequestNilsVacatedSlot covers both the swap-remove and last-element paths. Both fail on the unpatched code.

Verification

go vet, gofumpt -l, staticcheck, go build, go test -race ./..., and go test -tags debug -race ./... all pass.

@linkdata linkdata force-pushed the fix/core-retention-clear-slots branch from 0f4a98e to e5a2185 Compare June 18, 2026 03:57
Two GC-retention nits where a freed slice slot kept a stale reference live,
inconsistent with the deliberate reference-clearing elsewhere in the same files.

clearLocked reset the outbound queue with rq.wsQueue = rq.wsQueue[:0], leaving the
previous wire.WsMsg values (including Data, which carries full Inner/Replace/Append
HTML payloads) live in the backing array of a Request returned to the pool. A pooled
Request can sit idle indefinitely, pinning those payloads until a future reuse
overwrites each slot. This is inconsistent with the adjacent clear(rq.todoDirt) and
clear(rq.elems) (both commented as releasing references before pooling) and with
drainTailScript, which zeroes its freed slots. Add clear(rq.wsQueue) before the
reslice.

delRequest swap-removed an entry but never nilled the vacated tail slot, so the
backing array retained an otherwise-recyclable *Request pointer (the duplicated one
after a swap, or the original when removing the last element) for the session's
lifetime. Nil the freed slot before reslicing.

Neither is a correctness bug (all iterators use the resliced length), purely
retention. Add internal tests asserting the freed backing-array slots are zeroed.
@linkdata linkdata force-pushed the fix/core-retention-clear-slots branch from e5a2185 to 64ada8a Compare June 18, 2026 03:58
@linkdata linkdata merged commit f6264b5 into main Jun 18, 2026
6 checks passed
@linkdata linkdata deleted the fix/core-retention-clear-slots branch June 18, 2026 04:03
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