Fix sending results in callback flows

Launching new coroutines to deliver the results from the callback to the channel can lead to the results arriving out of order.
This commit is contained in:
cketti 2021-09-04 18:28:52 +02:00
parent a40189167c
commit 58498b8fc2
4 changed files with 23 additions and 16 deletions

View file

@ -3,6 +3,7 @@ package com.fsck.k9
import android.content.Context
import androidx.annotation.GuardedBy
import androidx.annotation.RestrictTo
import com.fsck.k9.helper.sendBlockingSilently
import com.fsck.k9.mail.MessagingException
import com.fsck.k9.mailstore.LocalStoreProvider
import com.fsck.k9.preferences.AccountManager
@ -18,7 +19,6 @@ import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.channels.Channel
import kotlinx.coroutines.channels.awaitClose
import kotlinx.coroutines.channels.sendBlocking
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.buffer
import kotlinx.coroutines.flow.callbackFlow
@ -126,11 +126,7 @@ class Preferences internal constructor(
val listener = AccountsChangeListener {
val account = getAccount(accountUuid)
if (account != null) {
try {
sendBlocking(account)
} catch (e: Exception) {
Timber.w(e, "Error while trying to send to channel")
}
sendBlockingSilently(account)
} else {
channel.close()
}

View file

@ -0,0 +1,16 @@
package com.fsck.k9.helper
import kotlinx.coroutines.channels.ClosedSendChannelException
import kotlinx.coroutines.channels.SendChannel
import kotlinx.coroutines.channels.sendBlocking
/**
* Like [sendBlocking], but ignores [ClosedSendChannelException].
*/
fun <E> SendChannel<E>.sendBlockingSilently(element: E) {
try {
sendBlocking(element)
} catch (e: ClosedSendChannelException) {
// Ignore
}
}

View file

@ -5,6 +5,7 @@ import com.fsck.k9.Account.FolderMode
import com.fsck.k9.DI
import com.fsck.k9.controller.MessagingController
import com.fsck.k9.controller.SimpleMessagingListener
import com.fsck.k9.helper.sendBlockingSilently
import com.fsck.k9.mail.FolderClass
import com.fsck.k9.preferences.AccountManager
import kotlinx.coroutines.CoroutineDispatcher
@ -19,7 +20,6 @@ import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.flatMapLatest
import kotlinx.coroutines.flow.flowOn
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.launch
import com.fsck.k9.mail.FolderType as RemoteFolderType
@OptIn(ExperimentalCoroutinesApi::class)
@ -64,9 +64,7 @@ class FolderRepository(
val listener = object : SimpleMessagingListener() {
override fun folderStatusChanged(statusChangedAccount: Account, folderId: Long) {
if (statusChangedAccount.uuid == account.uuid) {
launch {
send(getDisplayFolders(account, displayMode))
}
sendBlockingSilently(getDisplayFolders(account, displayMode))
}
}
}
@ -168,9 +166,7 @@ class FolderRepository(
send(getPushFolders(account, folderMode))
val listener = FolderSettingsChangedListener {
launch {
send(getPushFolders(account, folderMode))
}
sendBlockingSilently(getPushFolders(account, folderMode))
}
messageStore.addFolderSettingsChangedListener(listener)

View file

@ -12,6 +12,7 @@ import com.fsck.k9.AccountsChangeListener
import com.fsck.k9.Preferences
import com.fsck.k9.controller.MessageCounts
import com.fsck.k9.controller.MessageCountsProvider
import com.fsck.k9.helper.sendBlockingSilently
import com.fsck.k9.provider.EmailProvider
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.ExperimentalCoroutinesApi
@ -34,9 +35,7 @@ class AccountsViewModel(
send(preferences.accounts)
val accountsChangeListener = AccountsChangeListener {
launch {
send(preferences.accounts)
}
sendBlockingSilently(preferences.accounts)
}
preferences.addOnAccountsChangeListener(accountsChangeListener)