Skip to content

fix: complete disconnect() when the server closes the socket without echoing the leave - #1208

Draft
hiroshihorie wants to merge 1 commit into
mainfrom
hiroshi/complete-disconnect-on-socket-close
Draft

hiroshihorie wants to merge 1 commit into
mainfrom
hiroshi/complete-disconnect-on-socket-close

Conversation

@hiroshihorie

Copy link
Copy Markdown
Member

Problem

engine.disconnect() sends the Leave and relies on the server's echo to run cleanup and emit EngineDisconnectedEvent. Media nodes drop queued leave messages when they close the signal sink (pkg/routing/signal.go, signalMessageSink.Close, comment in place), so the echo can be lost. The socket close was then ignored because _isClosed was already set, and Room.disconnect() waited out its 10 s timeout for an event that never came, then threw without running its own cleanup.

Found by the e2e-flutter suite (livekit/e2e-flutter#7), where one agent per run hit it against a local livekit-server 1.13.6. Reproduced every run with LOG=fine: SignalClient did disconnect with no Leave received before it, while the server logged sendLeave: true.

Fix

The engine remembers a disconnect that has sent its Leave and is waiting for the echo. A socket close in that window runs cleanup and emits EngineDisconnectedEvent with the original reason. A close that arrives after the echo finds nothing pending and is ignored as before, so there is no second event.

One field and one branch in engine.dart. Independent of #1204.

Tests

Two in test/core/disconnect_event_test.dart: socket close without echo completes disconnect() in well under the timeout with one clientInitiated event, and echo followed by close still emits exactly one. The first fails on main.

🤖 Generated with Claude Code

…echoing the leave

engine.disconnect() sends the Leave and relies on the server's echo to
run cleanup and emit EngineDisconnectedEvent. Media nodes drop queued
leave messages when they close the signal sink, so the echo can be
lost. The socket close was then ignored because _isClosed was set, and
Room.disconnect() waited out its 10 s timeout for an event that never
came, leaving the room half torn down.

The engine now remembers a disconnect that is waiting for its echo and,
on a socket close in that window, runs cleanup and emits the event
itself. A close that follows the echo is still ignored, so there is no
second event.
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