fix(android): 使用同步标志修复参与方显示4/3的竞态条件bug
问题根因: - 之前使用异步的 sessionStatus 检查来防止 participant_joined 事件 在 session_started 之后继续添加参与方 - 但 sessionStatus 是通过 StateFlow 异步更新的,检查时状态可能还未更新 - 导致 participant_joined 事件仍能添加额外的参与方,显示4/3而非3/3 解决方案: - 添加同步标志 sessionStartedForSession: String? - 在 session_started 处理器的最开始同步设置此标志 - 在 participant_joined 处理器中检查此标志,而非异步状态 - 由于回调是顺序处理的,这种方式100%可靠 修改内容: 1. 添加 sessionStartedForSession 私有成员变量 2. 在 session_started 事件处理开始时立即设置标志 3. 在 participant_joined 事件处理开始时检查标志 4. 在所有 reset 方法中重置标志: - resetSessionState() - resetJoinKeygenState() - resetCoSignState() - resetTransferState() Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
1bc42c207a
commit
8a9a983cbd
|
|
@ -45,6 +45,11 @@ class MainViewModel @Inject constructor(
|
|||
private val _hasEnteredSession = MutableStateFlow(false)
|
||||
val hasEnteredSession: StateFlow<Boolean> = _hasEnteredSession.asStateFlow()
|
||||
|
||||
// Synchronous flag to prevent participant_joined from adding duplicates after session_started
|
||||
// This is set immediately (synchronously) when session_started is processed, ensuring
|
||||
// any subsequent participant_joined events in the same callback queue will see the flag
|
||||
private var sessionStartedForSession: String? = null
|
||||
|
||||
init {
|
||||
// Start initialization on app launch
|
||||
checkAllServices()
|
||||
|
|
@ -339,6 +344,12 @@ class MainViewModel @Inject constructor(
|
|||
|
||||
when (event.eventType) {
|
||||
"session_started" -> {
|
||||
// CRITICAL: Set flag immediately (synchronously) to prevent subsequent
|
||||
// participant_joined events from adding duplicates. This must be the
|
||||
// first line before any async operations.
|
||||
sessionStartedForSession = event.sessionId
|
||||
android.util.Log.d("MainViewModel", "Session started flag set for: ${event.sessionId}")
|
||||
|
||||
// Check if this is for keygen initiator (CreateWallet)
|
||||
val currentSessionId = _currentSessionId.value
|
||||
if (currentSessionId != null && event.sessionId == currentSessionId) {
|
||||
|
|
@ -396,11 +407,12 @@ class MainViewModel @Inject constructor(
|
|||
"party_joined", "participant_joined" -> {
|
||||
android.util.Log.d("MainViewModel", "Processing participant_joined event...")
|
||||
|
||||
// Don't add participants if keygen/sign has already started
|
||||
// This prevents duplicate additions after session_started event
|
||||
val currentStatus = repository.sessionStatus.value
|
||||
if (currentStatus == SessionStatus.IN_PROGRESS || currentStatus == SessionStatus.COMPLETED) {
|
||||
android.util.Log.d("MainViewModel", " Session already in progress/completed, ignoring participant_joined")
|
||||
// CRITICAL: Check synchronous flag first - if session_started was already
|
||||
// processed for this session, don't add more participants
|
||||
// This is 100% reliable because the flag is set synchronously in session_started
|
||||
// handler before any async operations, and callbacks are processed sequentially
|
||||
if (sessionStartedForSession == event.sessionId) {
|
||||
android.util.Log.d("MainViewModel", " Session already started for ${event.sessionId}, ignoring participant_joined")
|
||||
return@setSessionEventCallback
|
||||
}
|
||||
|
||||
|
|
@ -548,6 +560,8 @@ class MainViewModel @Inject constructor(
|
|||
_publicKey.value = null
|
||||
_createdInviteCode.value = null
|
||||
_hasEnteredSession.value = false
|
||||
// Reset synchronous flag for fresh session
|
||||
sessionStartedForSession = null
|
||||
// Reset session status to WAITING for fresh start
|
||||
repository.resetSessionStatus()
|
||||
}
|
||||
|
|
@ -740,6 +754,8 @@ class MainViewModel @Inject constructor(
|
|||
pendingJoinToken = ""
|
||||
pendingPassword = ""
|
||||
pendingJoinKeygenInfo = null
|
||||
// Reset synchronous flag for fresh session
|
||||
sessionStartedForSession = null
|
||||
// Reset session status to WAITING for fresh start
|
||||
repository.resetSessionStatus()
|
||||
}
|
||||
|
|
@ -925,6 +941,8 @@ class MainViewModel @Inject constructor(
|
|||
pendingCoSignInviteCode = ""
|
||||
pendingCoSignJoinToken = ""
|
||||
pendingJoinSignInfo = null
|
||||
// Reset synchronous flag for fresh session
|
||||
sessionStartedForSession = null
|
||||
// Reset session status to WAITING for fresh start
|
||||
repository.resetSessionStatus()
|
||||
}
|
||||
|
|
@ -1671,6 +1689,8 @@ class MainViewModel @Inject constructor(
|
|||
_signature.value = null
|
||||
_txHash.value = null
|
||||
pendingSignInitiatorInfo = null
|
||||
// Reset synchronous flag for fresh session
|
||||
sessionStartedForSession = null
|
||||
// Reset session status to WAITING for fresh start
|
||||
repository.resetSessionStatus()
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue