Use dispatch queue and join to ensure single-threaded requests.

This commit is contained in:
Alex Hart
2025-05-06 10:02:55 -03:00
committed by Michelle Tang
parent 93403a0d2c
commit 919cbbd7ca

View File

@@ -5,9 +5,11 @@
package org.thoughtcrime.securesms.components.settings.app.backups package org.thoughtcrime.securesms.components.settings.app.backups
import androidx.annotation.WorkerThread
import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope import androidx.lifecycle.viewModelScope
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Job
import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.distinctUntilChanged import kotlinx.coroutines.flow.distinctUntilChanged
@@ -16,7 +18,6 @@ import kotlinx.coroutines.flow.filter
import kotlinx.coroutines.flow.update import kotlinx.coroutines.flow.update
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import kotlinx.coroutines.rx3.asFlow import kotlinx.coroutines.rx3.asFlow
import kotlinx.coroutines.withContext
import org.signal.core.util.concurrent.SignalDispatchers import org.signal.core.util.concurrent.SignalDispatchers
import org.signal.core.util.logging.Log import org.signal.core.util.logging.Log
import org.signal.core.util.money.FiatMoney import org.signal.core.util.money.FiatMoney
@@ -43,28 +44,41 @@ class BackupsSettingsViewModel : ViewModel() {
val stateFlow: StateFlow<BackupsSettingsState> = internalStateFlow val stateFlow: StateFlow<BackupsSettingsState> = internalStateFlow
private val loadRequests = MutableSharedFlow<Unit>(extraBufferCapacity = 1)
init { init {
viewModelScope.launch(Dispatchers.Default) { viewModelScope.launch(SignalDispatchers.Default) {
InternetConnectionObserver.observe().asFlow() InternetConnectionObserver.observe().asFlow()
.distinctUntilChanged() .distinctUntilChanged()
.filter { it } .filter { it }
.drop(1) .drop(1)
.collect { .collect {
Log.d(TAG, "Triggering refresh from internet reconnect.") Log.d(TAG, "Triggering refresh from internet reconnect.")
loadEnabledState() loadRequests.tryEmit(Unit)
} }
} }
viewModelScope.launch(SignalDispatchers.Default) {
loadRequests.collect {
Log.d(TAG, "-- Dispatching state load.")
loadEnabledState().join()
Log.d(TAG, "-- Completed state load.")
}
}
}
override fun onCleared() {
Log.d(TAG, "ViewModel has been cleared.")
} }
fun refreshState() { fun refreshState() {
Log.d(TAG, "Refreshing state from manual call.") Log.d(TAG, "Refreshing state from manual call.")
viewModelScope.launch { loadRequests.tryEmit(Unit)
loadEnabledState()
}
} }
private suspend fun loadEnabledState() { @WorkerThread
withContext(SignalDispatchers.IO) { private fun loadEnabledState(): Job {
return viewModelScope.launch(SignalDispatchers.IO) {
if (!RemoteConfig.messageBackups || !AppDependencies.billingApi.isApiAvailable()) { if (!RemoteConfig.messageBackups || !AppDependencies.billingApi.isApiAvailable()) {
Log.w(TAG, "Paid backups are not available on this device.") Log.w(TAG, "Paid backups are not available on this device.")
internalStateFlow.update { it.copy(enabledState = BackupsSettingsState.EnabledState.NotAvailable, showBackupTierInternalOverride = false) } internalStateFlow.update { it.copy(enabledState = BackupsSettingsState.EnabledState.NotAvailable, showBackupTierInternalOverride = false) }