Realm transaction, use semaphore as suggested by Dominaezzz

This commit is contained in:
ganfra 2020-09-17 18:31:47 +02:00
parent 216138394f
commit 144d0e56cc

View file

@ -16,31 +16,52 @@
*/ */
package org.matrix.android.sdk.internal.database package org.matrix.android.sdk.internal.database
import com.zhuinden.monarchy.Monarchy
import io.realm.Realm import io.realm.Realm
import io.realm.RealmConfiguration import io.realm.RealmConfiguration
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.isActive import kotlinx.coroutines.isActive
import kotlinx.coroutines.launch
import kotlinx.coroutines.sync.Semaphore
import kotlinx.coroutines.sync.withPermit
import kotlinx.coroutines.withContext import kotlinx.coroutines.withContext
import timber.log.Timber import timber.log.Timber
suspend fun <T> awaitTransaction(config: RealmConfiguration, transaction: suspend (realm: Realm) -> T) = withContext(Dispatchers.Default) { internal fun <T> CoroutineScope.asyncTransaction(monarchy: Monarchy, transaction: suspend (realm: Realm) -> T) {
Realm.getInstance(config).use { bgRealm -> asyncTransaction(monarchy.realmConfiguration, transaction)
bgRealm.beginTransaction() }
val result: T
try { internal fun <T> CoroutineScope.asyncTransaction(realmConfiguration: RealmConfiguration, transaction: suspend (realm: Realm) -> T) {
val start = System.currentTimeMillis() launch {
result = transaction(bgRealm) awaitTransaction(realmConfiguration, transaction)
if (isActive) { }
bgRealm.commitTransaction() }
val end = System.currentTimeMillis()
val time = end - start private val realmSemaphore = Semaphore(1)
Timber.v("Execute transaction in $time millis")
} suspend fun <T> awaitTransaction(config: RealmConfiguration, transaction: suspend (realm: Realm) -> T): T {
} finally { return realmSemaphore.withPermit {
if (bgRealm.isInTransaction) { withContext(Dispatchers.IO) {
bgRealm.cancelTransaction() Realm.getInstance(config).use { bgRealm ->
} bgRealm.beginTransaction()
} val result: T
result try {
val start = System.currentTimeMillis()
result = transaction(bgRealm)
if (isActive) {
bgRealm.commitTransaction()
val end = System.currentTimeMillis()
val time = end - start
Timber.v("Execute transaction in $time millis")
}
} finally {
if (bgRealm.isInTransaction) {
bgRealm.cancelTransaction()
}
}
result
}
}
} }
} }