presence: count doc/snapshot listeners toward a room's emptiness - #485
Merged
TheGreatAxios merged 2 commits intoAug 30, 2026
Merged
TheGreatAxios merged 2 commits into
TheGreatAxios merged 2 commits into
Conversation
destroyRoomIfEmpty's emptiness check only looks at clientIdByPrincipal and listeners, so a room kept alive only by a subscribeDocUpdates or subscribeSnapshots listener is destroyed and silently recreated on the next empty join/leave cycle, permanently orphaning that listener.
destroyRoomIfEmpty now treats a room as non-empty while it still has a subscribeDocUpdates or subscribeSnapshots listener, not just presence members and subscribe() listeners, and both of those subscriptions' teardown paths now attempt cleanup themselves so a room kept alive only by one of them still gets torn down once that listener goes away.
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.
Stacked on #484 (CL-7205)
This branch is stacked on
cl-7205-room-registry-destroy(CL-7205, PR #484) — it targets that branch, notmain, because both fix the samedestroyRoomIfEmptyfunction inpackages/presence/src/room-registry.ts. Merge #484 first; this PR's diff (once #484 lands) will be just the two commits below.Summary
Fixes CL-7204 (Medium).
destroyRoomIfEmpty's emptiness check only looked atclientIdByPrincipalandlisteners, ignoringdocListenersandsnapshotListeners— both populated through the registry's own public API (subscribeDocUpdates,subscribeSnapshots) independently ofsubscribe/join. A room kept alive only by one of those two listener sets was destroyed and silently recreated on the next otherwise-empty join/leave cycle, permanently orphaning that listener (it's invoked by the destroyed room's oldSet, or never again).What changed
isRoomEmpty(introduced in CL-7205) now also checksdocListeners.size === 0andsnapshotListeners.size === 0.subscribeDocUpdatesandsubscribeSnapshots's returned unsubscribe callbacks now also calldestroyRoomIfEmpty— previously onlysubscribe's unsubscribe andleave/sweepStaledid. Without this, broadening the emptiness check would introduce a new leak: a room kept alive only by a doc/snapshot listener would never get cleaned up once that listener goes away.Test plan
WORKBENCH_CHECK_SINCE=origin/main bun run typecheck— clean across all 6 affected packagesWORKBENCH_CHECK_SINCE=origin/main bun run test— all greenbun run lint— cleanbun run check:structural— clean