From 50cb10d6a81ae4be4c3afc9ba046101a7acc836c Mon Sep 17 00:00:00 2001 From: hailin Date: Thu, 1 Jan 2026 08:10:15 -0800 Subject: [PATCH] fix(android): improve session_started polling with multiple attempts MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Changed from single 2-second delay to 5 attempts at 500ms intervals. This provides faster detection while covering a longer window (2.5 seconds total). The polling loop: - Checks every 500ms for up to 5 times - Stops immediately if keygen is already triggered - Stops if session context changes (user cancelled/navigated away) This handles the case where the last joiner triggers session_started but cannot receive the event themselves. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 --- .../presentation/viewmodel/MainViewModel.kt | 20 +++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/backend/mpc-system/services/service-party-android/app/src/main/java/com/durian/tssparty/presentation/viewmodel/MainViewModel.kt b/backend/mpc-system/services/service-party-android/app/src/main/java/com/durian/tssparty/presentation/viewmodel/MainViewModel.kt index d2838a25..94a22202 100644 --- a/backend/mpc-system/services/service-party-android/app/src/main/java/com/durian/tssparty/presentation/viewmodel/MainViewModel.kt +++ b/backend/mpc-system/services/service-party-android/app/src/main/java/com/durian/tssparty/presentation/viewmodel/MainViewModel.kt @@ -504,20 +504,28 @@ class MainViewModel @Inject constructor( startKeygenAsJoiner() } else { // Otherwise, wait for session_started event - // But also poll session status after a delay in case we missed the event + // But also poll session status immediately and after delays in case we missed the event // This handles the race condition where session_started is sent before we're ready + // The last joiner triggers session_started but can't receive it themselves viewModelScope.launch { - delay(2000) // Wait 2 seconds - val joinInfo = pendingJoinKeygenInfo - if (joinInfo != null && joinInfo.sessionId == sessionInfo.sessionId) { - android.util.Log.d("MainViewModel", "Checking session status after delay...") + // Poll multiple times with short delays + for (attempt in 1..5) { + delay(500) // Check every 500ms + val joinInfo = pendingJoinKeygenInfo + if (joinInfo == null || joinInfo.sessionId != sessionInfo.sessionId) { + android.util.Log.d("MainViewModel", "Polling cancelled - keygen already started or session changed") + break + } + android.util.Log.d("MainViewModel", "Polling session status (attempt $attempt)...") val statusResult = repository.getSessionStatus(sessionInfo.sessionId) statusResult.onSuccess { status -> if (status.status == "in_progress" && pendingJoinKeygenInfo != null) { - android.util.Log.d("MainViewModel", "Session is now in_progress (detected via polling), triggering keygen") + android.util.Log.d("MainViewModel", "Session is now in_progress (detected via polling attempt $attempt), triggering keygen") startKeygenAsJoiner() } } + // If keygen was triggered, break out of loop + if (pendingJoinKeygenInfo == null) break } } }