From 0676fc2e47eb969dd7d354612911756bd664c90f Mon Sep 17 00:00:00 2001 From: zarazaex69 Date: Sat, 16 May 2026 00:09:41 +0300 Subject: [PATCH] fix(engine): delay session close teardown 2s --- internal/engine/goolom/lifecycle.go | 7 ++++++- internal/engine/livekit/livekit.go | 8 ++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/internal/engine/goolom/lifecycle.go b/internal/engine/goolom/lifecycle.go index e340e91..316107f 100644 --- a/internal/engine/goolom/lifecycle.go +++ b/internal/engine/goolom/lifecycle.go @@ -197,8 +197,13 @@ func (s *Session) Close() error { if !alreadyClosing { leaveUID := uuid.New().String() leaveAck := s.registerAckWaiter(leaveUID) + // 2s matches our jitsi tear-down budget. The reason is the same: + // without giving the server time to register the leave, a + // back-to-back reconnection from the same client collides with a + // still-alive ghost participant on the SFU side and inherits + // stale media-flow state. if s.sendLeave(leaveUID) { - _ = s.waitForAck(leaveUID, leaveAck, 1500*time.Millisecond) + _ = s.waitForAck(leaveUID, leaveAck, 2*time.Second) } else { s.removeAckWaiter(leaveUID) } diff --git a/internal/engine/livekit/livekit.go b/internal/engine/livekit/livekit.go index 1d41c9d..fcc9749 100644 --- a/internal/engine/livekit/livekit.go +++ b/internal/engine/livekit/livekit.go @@ -188,6 +188,14 @@ func (s *Session) Close() error { if s.room != nil { s.unpublishLocalTracks() s.room.Disconnect() + // LiveKit's Disconnect() returns once the local SDK state + // is torn down, not when the server has actually evicted + // the participant. Without giving the signalling channel + // time to flush the LEAVE_REQUEST and the server to act on + // it, a back-to-back reconnect from the same identity in + // the same room sees a still-alive ghost participant on + // the SFU and inherits stale publication state. + time.Sleep(2 * time.Second) } close(s.sendQueue) s.wg.Wait()