Files
livekit/pkg/rtc
sujan-talviewandClaude Opus 5 26b5d656aa rtc: keep the participant egress guard across a duplicate identity eviction (#5099)
* rtc: keep the participant egress guard across a duplicate identity eviction

Room.RemoveParticipant clears hasPublished[identity], which is the guard that
stops auto participant egress launching twice for the same identity. A duplicate
identity eviction calls RemoveParticipant with the outgoing participant's own ID,
so the "participant session has been replaced" early return does not apply and
the guard is dropped even though the identity stays in the room.

The replacement session then publishes, finds no guard and launches a second
participant egress. The first one does not stop: the egress SDK resolves its
source by identity, so it follows the new SID, re-subscribes to the republished
tracks and keeps recording. Both jobs then write the same media until the
participant leaves for good.

Keep the guard when the close reason is ParticipantCloseReasonDuplicateIdentity.
launchedTrackEgresses is left as is, since it is keyed per track ID and a
replacement session republishes with new track IDs.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

* rtc: separate the participant egress launch guard from hasPublished

Review feedback on the first commit: hasPublished gates the publisher agent
dispatch as well as participant egress, so preserving it across a duplicate
identity eviction left the replacement session without its publisher jobs.

Track the participant egress launch in its own identity keyed map. hasPublished
is cleared on every removal as before, so agent dispatch is untouched, and only
the egress guard survives a duplicate identity eviction.

The preserved guard is also tied to a successful handoff: StartSession releases
it when the session that caused the eviction fails to join, so it cannot strand
an identity that is no longer in the room.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

* rtc: only release a preserved egress guard while the identity is unoccupied

Sessions for one identity can race. A handoff fails with ErrAlreadyJoined
exactly when another session has already joined under that identity, and that
session now owns the preserved participant egress guard. Releasing it there let
the winner start a second egress on its next publication, alongside the job
still recording.

Release the guard only while the room holds no participant for the identity.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

* rtc: drop the failed handoff release of the egress guard

Review feedback: the duplicate identity disconnect is filtered, so the running
participant egress keeps recording whether or not the replacement session ever
joins. Releasing the guard on a failed handoff only gives the next session for
that identity a way to launch a second job against the same tracks.

Remove ClearLaunchedParticipantEgress and its StartSession deferred call. The
guard is now released solely by RemoveParticipant on a non-duplicate removal or
a room close, which is where the identity genuinely leaves.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
2026-11-12 10:43:14 -05:00
..
2024-03-21 02:48:26 -07:00
2025-08-28 05:20:25 -07:00