Should fix realm crash loop

This commit is contained in:
ganfra 2020-07-20 16:42:56 +02:00
parent 27207a27ae
commit 0d51c160eb
2 changed files with 20 additions and 7 deletions

View file

@ -24,6 +24,7 @@ import im.vector.matrix.android.internal.crypto.algorithms.olm.OlmDecryptionResu
import im.vector.matrix.android.internal.database.mapper.asDomain import im.vector.matrix.android.internal.database.mapper.asDomain
import im.vector.matrix.android.internal.database.model.EventEntity import im.vector.matrix.android.internal.database.model.EventEntity
import im.vector.matrix.android.internal.database.model.EventInsertEntity import im.vector.matrix.android.internal.database.model.EventInsertEntity
import im.vector.matrix.android.internal.database.model.EventInsertEntityFields
import im.vector.matrix.android.internal.database.query.where import im.vector.matrix.android.internal.database.query.where
import im.vector.matrix.android.internal.di.SessionDatabase import im.vector.matrix.android.internal.di.SessionDatabase
import im.vector.matrix.android.internal.session.EventInsertLiveProcessor import im.vector.matrix.android.internal.session.EventInsertLiveProcessor
@ -46,17 +47,25 @@ internal class EventInsertLiveObserver @Inject constructor(@SessionDatabase real
if (!results.isLoaded || results.isEmpty()) { if (!results.isLoaded || results.isEmpty()) {
return return
} }
val idsToDeleteAfterProcess = ArrayList<String>()
val filteredEvents = ArrayList<EventInsertEntity>(results.size)
Timber.v("EventInsertEntity updated with ${results.size} results in db") Timber.v("EventInsertEntity updated with ${results.size} results in db")
val filteredEvents = results.mapNotNull { results.forEach {
if (shouldProcess(it)) { if (shouldProcess(it)) {
results.realm.copyFromRealm(it) // don't use copy from realm over there
} else { val copiedEvent = EventInsertEntity(
null eventId = it.eventId,
eventType = it.eventType
).apply {
insertType = it.insertType
}
filteredEvents.add(copiedEvent)
} }
idsToDeleteAfterProcess.add(it.eventId)
} }
Timber.v("There are ${filteredEvents.size} events to process")
observerScope.launch { observerScope.launch {
awaitTransaction(realmConfiguration) { realm -> awaitTransaction(realmConfiguration) { realm ->
Timber.v("##Transaction: There are ${filteredEvents.size} events to process ")
filteredEvents.forEach { eventInsert -> filteredEvents.forEach { eventInsert ->
val eventId = eventInsert.eventId val eventId = eventInsert.eventId
val event = EventEntity.where(realm, eventId).findFirst() val event = EventEntity.where(realm, eventId).findFirst()
@ -72,7 +81,10 @@ internal class EventInsertLiveObserver @Inject constructor(@SessionDatabase real
it.process(realm, domainEvent) it.process(realm, domainEvent)
} }
} }
realm.delete(EventInsertEntity::class.java) realm.where(EventInsertEntity::class.java)
.`in`(EventInsertEntityFields.EVENT_ID, idsToDeleteAfterProcess.toTypedArray())
.findAll()
.deleteAllFromRealm()
} }
} }
} }

View file

@ -26,6 +26,7 @@ import io.realm.RealmObject
import io.realm.RealmResults import io.realm.RealmResults
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.SupervisorJob import kotlinx.coroutines.SupervisorJob
import kotlinx.coroutines.android.asCoroutineDispatcher
import kotlinx.coroutines.cancelChildren import kotlinx.coroutines.cancelChildren
import java.util.concurrent.atomic.AtomicBoolean import java.util.concurrent.atomic.AtomicBoolean
import java.util.concurrent.atomic.AtomicReference import java.util.concurrent.atomic.AtomicReference
@ -39,7 +40,7 @@ internal abstract class RealmLiveEntityObserver<T : RealmObject>(protected val r
val BACKGROUND_HANDLER = createBackgroundHandler("LIVE_ENTITY_BACKGROUND") val BACKGROUND_HANDLER = createBackgroundHandler("LIVE_ENTITY_BACKGROUND")
} }
protected val observerScope = CoroutineScope(SupervisorJob()) protected val observerScope = CoroutineScope(SupervisorJob() + BACKGROUND_HANDLER.asCoroutineDispatcher())
protected abstract val query: Monarchy.Query<T> protected abstract val query: Monarchy.Query<T>
private val isStarted = AtomicBoolean(false) private val isStarted = AtomicBoolean(false)
private val backgroundRealm = AtomicReference<Realm>() private val backgroundRealm = AtomicReference<Realm>()