Skip to content

Always emit Disconnected on engine close#1096

Merged
MaxHeimbrock merged 2 commits into
mainfrom
max/fix-engine-close-disconnect-event
May 19, 2026
Merged

Always emit Disconnected on engine close#1096
MaxHeimbrock merged 2 commits into
mainfrom
max/fix-engine-close-disconnect-event

Conversation

@MaxHeimbrock
Copy link
Copy Markdown
Contributor

@MaxHeimbrock MaxHeimbrock commented May 15, 2026

Summary

RtcEngineInner::close only emitted EngineEvent::Disconnected from inside the if let Some(engine_task) block. Each failed try_restart_connection calls running_handle.engine_task.take() and does not restore it on error, so after the reconnect loop exhausts all attempts and calls close(UnknownReason), engine_task is already None and the disconnect event is never sent. The room task never runs handle_disconnected, the connection state stays at Reconnecting, and RoomEvent::Disconnected is never dispatched — consumers see the room appear permanently stuck in reconnect after a network outage.

Repro

Use Unity SDK Meet sample and lock the screen. Android will remove network access to the app and it will try 10 reconnects, until it fails eventually. In browser I can observe the Android participant being removed.
Unlock Android phone again and without the fix, I did not receive a Room.OnDisconnected event, the state is still Reconnecting and not disconnected.

Changes

Move the emit outside the if-let so the event always fires on close. Duplicates are absorbed by update_connection_state on the room side.

`RtcEngineInner::close` only emitted `EngineEvent::Disconnected` from
inside the `if let Some(engine_task)` block. Each failed
`try_restart_connection` calls `running_handle.engine_task.take()` and
does not restore it on error, so after the reconnect loop exhausts all
attempts and calls `close(UnknownReason)`, `engine_task` is already
`None` and the disconnect event is never sent. The room task never
runs `handle_disconnected`, the connection state stays at Reconnecting,
and `RoomEvent::Disconnected` is never dispatched — consumers see the
room appear permanently stuck in reconnect after a network outage.

Move the emit outside the if-let so the event always fires on close.
Duplicates are absorbed by `update_connection_state` on the room side.
@MaxHeimbrock MaxHeimbrock requested a review from ladvoc as a code owner May 15, 2026 14:03
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 15, 2026

Changeset

The following package versions will be affected by this PR:

Package Bump
livekit patch
livekit-ffi patch

Copy link
Copy Markdown
Contributor

@ladvoc ladvoc left a comment

Choose a reason for hiding this comment

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

LGTM ✅

// prior failed `try_restart_connection`. Without this, a reconnect cycle that
// exhausts all attempts leaves the room stuck in Reconnecting forever because
// the room's task never sees the event that drives `handle_disconnected`.
let _ = self.engine_tx.send(EngineEvent::Disconnected { reason });
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.

any chance that there could be duplicated disconnected events ?

what will happen if close() is called multiple times ?

@xianshijing-lk
Copy link
Copy Markdown
Contributor

I'm OK with this quick fix for now, but we should review the connection state machine more carefully.

@MaxHeimbrock MaxHeimbrock merged commit b286e7e into main May 19, 2026
22 checks passed
@MaxHeimbrock MaxHeimbrock deleted the max/fix-engine-close-disconnect-event branch May 19, 2026 08:26
@knope-bot knope-bot Bot mentioned this pull request May 19, 2026
@MaxHeimbrock
Copy link
Copy Markdown
Contributor Author

I'm OK with this quick fix for now, but we should review the connection state machine more carefully.

Lets do that, saw your post on Slack and I also think this is the right way if we can spend the time.

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.

3 participants