Call-to-call switch: send an explicit HangupCall before disposing the embed (transient ghost RTC membership) #195

Closed
opened 2026-09-17 23:24:13 -04:00 by jared · 1 comment
Owner

Migrated from LOTUS_TODO.md on 2026-09-17 (the file is now reference-only).

[Low] [live] Call-to-call switch disposes the embed without an explicit HangupCall → possible transient ghost RTC membership until EC's unload-leave fires.

Related: #29 (logout mid-call never hangs up) — same root cause family; fix both in one pass.

_Migrated from `LOTUS_TODO.md` on 2026-09-17 (the file is now reference-only)._ **[Low] [live]** Call-to-call switch disposes the embed without an explicit `HangupCall` → possible transient ghost RTC membership until EC's unload-leave fires. Related: #29 (logout mid-call never hangs up) — same root cause family; fix both in one pass.
jared added this to the Features 2026-Q4 milestone 2026-09-17 23:24:13 -04:00
jared added the bugpriority: lowarea: calls labels 2026-09-17 23:24:13 -04:00
Author
Owner

Fixed in 070a1ea0. Measured first: answering a DM call from the in-call banner while in Voice Lounge left alice's m.call.member in the lounge for 17 s (until the delayed leave expired).

Now handleAnswer (the only call-to-call switch path — the sidebar/prescreen/header paths all refuse while in a call) hangs up explicitly, waits for our membership to clear (bounded 4 s; hangupCallAndWait moved out of LogoutDialog into plugins/call/hangup.ts so #29 and this share it), disposes the old embed itself, then joins the new call. The explicit dispose matters: without it the old embed's HangupCall echo landed after startCall() and cleared the new embed from the atom (seen in testing — the DM call never started).

After: old membership gone in 1 s, new DM call live with both participants in io.lotus.call_state.

Fixed in `070a1ea0`. Measured first: answering a DM call from the in-call banner while in Voice Lounge left alice's `m.call.member` in the lounge for **17 s** (until the delayed leave expired). Now `handleAnswer` (the only call-to-call switch path — the sidebar/prescreen/header paths all refuse while in a call) hangs up explicitly, waits for our membership to clear (bounded 4 s; `hangupCallAndWait` moved out of LogoutDialog into `plugins/call/hangup.ts` so #29 and this share it), disposes the old embed itself, then joins the new call. The explicit dispose matters: without it the old embed's HangupCall echo landed *after* `startCall()` and cleared the new embed from the atom (seen in testing — the DM call never started). After: old membership gone in **1 s**, new DM call live with both participants in `io.lotus.call_state`.
jared closed this issue 2026-09-19 12:21:31 -04:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: LotusGuild/cinny#195