Skip to content

Resolve memory leak for server-initiated room closure - #1473

Open
alan-george-lk wants to merge 3 commits into
mainfrom
alan/bugfix-remote-room-closure
Open

alan-george-lk wants to merge 3 commits into
mainfrom
alan/bugfix-remote-room-closure

Conversation

@alan-george-lk

@alan-george-lk alan-george-lk commented Sep 29, 2026 •

Copy link
Copy Markdown
Contributor

This fixes a fairly hefty memory leak reported by a customer. Their use case is remotely killing a room via server API, which kills the client room locally, and joining another room in the same client process.

Testing summary below, where a "cycle" is a single process that:

  1. Creates a room
  2. Audio + 720p video sources publish some data
  3. Wait for livekit --dev room delete <room name>
  4. Repeat
Repeated lifecycle iterations Peak/final RSS before Peak RSS after
1,000 cycles ~1.35 GiB 41.05 MiB

Previously, unpublish_track called remove_track(sender)? first. When a remote room deletion had already closed the connection, that call errored and returned early, leaving the publication → track → transceiver graph attached, which could retain the room session.

The patch:

  • Saves the remove_track result instead of returning immediately.
  • Always detaches the transceiver and clears the publication’s track reference.
  • Requests renegotiation only when sender removal succeeded.
  • Returns the original removal error only after cleanup.

The added reconnection test publishes a local video track, deletes the room remotely, then verifies both that the publication loses its track and that the room session can actually drop. That directly demonstrates the retained-reference lifecycle issue is resolved.

I cut a specific C++ SDK branch build against this fix and the customer confirmed this resolved the problem.

@github-actions

github-actions Bot commented Sep 29, 2026 •

Copy link
Copy Markdown
Contributor

Changeset ✓

This PR includes a changeset covering all affected packages:

Package Bump
livekit patch
livekit-capture patch
livekit-ffi patch

@devin-ai-integration devin-ai-integration Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Devin Review found 1 potential issue.

1 flag not posted on this PR by your GitHub settings — view it in Devin Review. (Configure)

Devin Review

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Failed unpublish sends contradictory binding events

When sender removal fails, unpublish_track now emits LocalTrackUnpublished but returns an error. The FFI unpublish request forwards that event, then reports failure to its caller.

(Refers to this code)

Learn more

The room emits LocalTrackUnpublished from this callback. The FFI event handler forwards it and removes the publication lookup entry. Meanwhile, the FFI request treats unpublish_track's returned error as a failed operation and sends an error callback. A closed peer connection triggers this mismatch even though the local track has been detached. Clients can receive a publication-removed event alongside a failed unpublish request.

Example: A participant unpublishes camera TR_1 while a server deletion closes its connection. Sender removal fails, so the SDK detaches TR_1 and sends LocalTrackUnpublished; the FFI request then reports an error for the same unpublish.

Recommended fix: Decide how the API represents completed local cleanup after sender-removal failure. Coordinate the unpublish_track return value with FFI's callback and event forwarding so the same operation has one consistent outcome; preserve the underlying removal error through logging or a distinct diagnostic if it cannot be returned as the operation result.

Devin Review


Was this helpful? React with 👍 or 👎 to provide feedback.

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