From a1dd0e254c72954b2ff65cb8bca69324cb5ef78f Mon Sep 17 00:00:00 2001 From: Lotus CI Date: Sun, 18 Oct 2026 02:47:36 -0400 Subject: [PATCH] fix(lotus): a homeserver stall shorter than the delayed-leave window no longer ends the call (#46) maximumNetworkErrorRetryCount was sized to min(sync grace period, leave delay), i.e. 10 s, so the membership manager gave up 20-35 s into a homeserver stall and showed "Connection lost", even when the server would keep the membership for 60 s (prod config). Size it to the leave delay instead: the embedded call has no /sync loop for the grace period to describe, and the server's delayed leave is what actually ends the membership. Fixes #46 Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_017PCb59uY3UKqDqt7B6hzd5 --- .../CallViewModel/localMember/LocalMember.ts | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/src/state/CallViewModel/localMember/LocalMember.ts b/src/state/CallViewModel/localMember/LocalMember.ts index 2f4fde26..a0a10fdc 100644 --- a/src/state/CallViewModel/localMember/LocalMember.ts +++ b/src/state/CallViewModel/localMember/LocalMember.ts @@ -868,16 +868,19 @@ export function enterRTCSession( }; } - // Calculates `maximumNetworkErrorRetryCount`. The connection is failed if EITHER: - // - The /sync loop is unresponsive for > `gracePeriod` ms, or - // - A delayed leave event is emitted (after `leaveDelay` ms period). - // Note: Use leaveDelay >> gracePeriod for delegated leave events. + // Calculates `maximumNetworkErrorRetryCount`: enough retries to outlast the + // server's delayed-leave window (see [lotus #46] below). const gracePeriod = Config.get().sync_disconnect_grace_period_ms; const leaveDelay = matrixRtcSessionConfig?.delayed_leave_event_delay_ms; const retryInterval = matrixRtcSessionConfig?.network_error_retry_ms; - // Math.min is used to account for the respective worst case: /sync not available or leave event emitted. - const maxWaitTime = Math.min(gracePeriod, leaveDelay); + // [lotus #46] Keep retrying for as long as the homeserver itself would keep + // our membership: until its delayed leave fires (`leaveDelay`). Capping at + // the 10 s sync grace period made a ~20–35 s homeserver stall end everyone's + // call ("Connection lost") even with a 60 s server-side leave delay. The + // embedded call has no /sync loop of its own, so the grace period doesn't + // describe anything it can observe. + const maxWaitTime = Math.max(gracePeriod, leaveDelay); const maximumNetworkErrorRetryCount = Math.ceil(maxWaitTime / retryInterval) + 1;