LiveObservers: launch directly coroutines

This commit is contained in:
ganfra 2019-12-18 16:59:45 +01:00
parent 4c88c12cfe
commit 7697278bb2
9 changed files with 80 additions and 65 deletions

View File

@ -19,12 +19,16 @@ package im.vector.matrix.android.internal.database
import com.zhuinden.monarchy.Monarchy import com.zhuinden.monarchy.Monarchy
import im.vector.matrix.android.internal.util.createBackgroundHandler import im.vector.matrix.android.internal.util.createBackgroundHandler
import io.realm.* import io.realm.*
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.SupervisorJob
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
internal interface LiveEntityObserver { internal interface LiveEntityObserver {
fun start() fun start()
fun dispose() fun dispose()
fun cancelProcess()
fun isStarted(): Boolean fun isStarted(): Boolean
} }
@ -35,6 +39,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 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>()
@ -59,10 +64,15 @@ internal abstract class RealmLiveEntityObserver<T : RealmObject>(protected val r
backgroundRealm.getAndSet(null).also { backgroundRealm.getAndSet(null).also {
it.close() it.close()
} }
observerScope.coroutineContext.cancelChildren()
} }
} }
} }
override fun cancelProcess() {
observerScope.coroutineContext.cancelChildren()
}
override fun isStarted(): Boolean { override fun isStarted(): Boolean {
return isStarted.get() return isStarted.get()
} }

View File

@ -173,6 +173,7 @@ internal class DefaultSession @Inject constructor(override val sessionParams: Se
override fun clearCache(callback: MatrixCallback<Unit>) { override fun clearCache(callback: MatrixCallback<Unit>) {
stopSync() stopSync()
stopAnyBackgroundSync() stopAnyBackgroundSync()
liveEntityObservers.forEach { it.cancelProcess() }
cacheService.get().clearCache(callback) cacheService.get().clearCache(callback)
} }

View File

@ -22,6 +22,7 @@ import androidx.work.WorkManager
import com.zhuinden.monarchy.Monarchy import com.zhuinden.monarchy.Monarchy
import im.vector.matrix.android.api.session.room.model.Membership import im.vector.matrix.android.api.session.room.model.Membership
import im.vector.matrix.android.internal.database.RealmLiveEntityObserver import im.vector.matrix.android.internal.database.RealmLiveEntityObserver
import im.vector.matrix.android.internal.database.awaitTransaction
import im.vector.matrix.android.internal.database.model.GroupEntity import im.vector.matrix.android.internal.database.model.GroupEntity
import im.vector.matrix.android.internal.database.model.GroupSummaryEntity import im.vector.matrix.android.internal.database.model.GroupSummaryEntity
import im.vector.matrix.android.internal.database.query.where import im.vector.matrix.android.internal.database.query.where
@ -31,6 +32,7 @@ import im.vector.matrix.android.internal.worker.WorkManagerUtil.matrixOneTimeWor
import im.vector.matrix.android.internal.worker.WorkerParamsFactory import im.vector.matrix.android.internal.worker.WorkerParamsFactory
import io.realm.OrderedCollectionChangeSet import io.realm.OrderedCollectionChangeSet
import io.realm.RealmResults import io.realm.RealmResults
import kotlinx.coroutines.launch
import javax.inject.Inject import javax.inject.Inject
private const val GET_GROUP_DATA_WORKER = "GET_GROUP_DATA_WORKER" private const val GET_GROUP_DATA_WORKER = "GET_GROUP_DATA_WORKER"
@ -53,10 +55,15 @@ internal class GroupSummaryUpdater @Inject constructor(private val context: Cont
.map { it.groupId } .map { it.groupId }
.toList()) .toList())
deleteGroups(modifiedGroupEntity modifiedGroupEntity
.filter { it.membership == Membership.LEAVE } .filter { it.membership == Membership.LEAVE }
.map { it.groupId } .map { it.groupId }
.toList()) .toList()
.also {
observerScope.launch {
deleteGroups(it)
}
}
} }
private fun fetchGroupsData(groupIds: List<String>) { private fun fetchGroupsData(groupIds: List<String>) {
@ -77,12 +84,9 @@ internal class GroupSummaryUpdater @Inject constructor(private val context: Cont
/** /**
* Delete the GroupSummaryEntity of left groups * Delete the GroupSummaryEntity of left groups
*/ */
private fun deleteGroups(groupIds: List<String>) { private suspend fun deleteGroups(groupIds: List<String>) = awaitTransaction(monarchy.realmConfiguration) { realm ->
monarchy
.writeAsync { realm ->
GroupSummaryEntity.where(realm, groupIds) GroupSummaryEntity.where(realm, groupIds)
.findAll() .findAll()
.deleteAllFromRealm() .deleteAllFromRealm()
} }
}
} }

View File

@ -23,11 +23,10 @@ import im.vector.matrix.android.internal.database.model.EventEntity
import im.vector.matrix.android.internal.database.query.types import im.vector.matrix.android.internal.database.query.types
import im.vector.matrix.android.internal.di.SessionDatabase import im.vector.matrix.android.internal.di.SessionDatabase
import im.vector.matrix.android.internal.di.UserId import im.vector.matrix.android.internal.di.UserId
import im.vector.matrix.android.internal.task.TaskExecutor
import im.vector.matrix.android.internal.task.configureWith
import io.realm.OrderedCollectionChangeSet import io.realm.OrderedCollectionChangeSet
import io.realm.RealmConfiguration import io.realm.RealmConfiguration
import io.realm.RealmResults import io.realm.RealmResults
import kotlinx.coroutines.launch
import timber.log.Timber import timber.log.Timber
import javax.inject.Inject import javax.inject.Inject
@ -39,8 +38,7 @@ import javax.inject.Inject
internal class EventRelationsAggregationUpdater @Inject constructor(@SessionDatabase realmConfiguration: RealmConfiguration, internal class EventRelationsAggregationUpdater @Inject constructor(@SessionDatabase realmConfiguration: RealmConfiguration,
@UserId private val userId: String, @UserId private val userId: String,
private val task: EventRelationsAggregationTask, private val task: EventRelationsAggregationTask) :
private val taskExecutor: TaskExecutor) :
RealmLiveEntityObserver<EventEntity>(realmConfiguration) { RealmLiveEntityObserver<EventEntity>(realmConfiguration) {
override val query = Monarchy.Query<EventEntity> { override val query = Monarchy.Query<EventEntity> {
@ -63,6 +61,8 @@ internal class EventRelationsAggregationUpdater @Inject constructor(@SessionData
insertedDomains, insertedDomains,
userId userId
) )
task.configureWith(params).executeBy(taskExecutor) observerScope.launch {
task.execute(params)
}
} }
} }

View File

@ -23,6 +23,7 @@ import im.vector.matrix.android.api.session.events.model.toModel
import im.vector.matrix.android.api.session.room.model.VersioningState import im.vector.matrix.android.api.session.room.model.VersioningState
import im.vector.matrix.android.api.session.room.model.create.RoomCreateContent import im.vector.matrix.android.api.session.room.model.create.RoomCreateContent
import im.vector.matrix.android.internal.database.RealmLiveEntityObserver import im.vector.matrix.android.internal.database.RealmLiveEntityObserver
import im.vector.matrix.android.internal.database.awaitTransaction
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.RoomSummaryEntity import im.vector.matrix.android.internal.database.model.RoomSummaryEntity
@ -30,9 +31,9 @@ import im.vector.matrix.android.internal.database.query.types
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 io.realm.OrderedCollectionChangeSet import io.realm.OrderedCollectionChangeSet
import io.realm.Realm
import io.realm.RealmConfiguration import io.realm.RealmConfiguration
import io.realm.RealmResults import io.realm.RealmResults
import kotlinx.coroutines.launch
import javax.inject.Inject import javax.inject.Inject
internal class RoomCreateEventLiveObserver @Inject constructor(@SessionDatabase internal class RoomCreateEventLiveObserver @Inject constructor(@SessionDatabase
@ -51,12 +52,13 @@ internal class RoomCreateEventLiveObserver @Inject constructor(@SessionDatabase
} }
.toList() .toList()
.also { .also {
observerScope.launch {
handleRoomCreateEvents(it) handleRoomCreateEvents(it)
} }
} }
}
private fun handleRoomCreateEvents(createEvents: List<Event>) = Realm.getInstance(realmConfiguration).use { private suspend fun handleRoomCreateEvents(createEvents: List<Event>) = awaitTransaction(realmConfiguration) { realm ->
it.executeTransactionAsync { realm ->
for (event in createEvents) { for (event in createEvents) {
val createRoomContent = event.getClearContent().toModel<RoomCreateContent>() val createRoomContent = event.getClearContent().toModel<RoomCreateContent>()
val predecessorRoomId = createRoomContent?.predecessor?.roomId ?: continue val predecessorRoomId = createRoomContent?.predecessor?.roomId ?: continue
@ -67,5 +69,4 @@ internal class RoomCreateEventLiveObserver @Inject constructor(@SessionDatabase
realm.insertOrUpdate(predecessorRoomSummary) realm.insertOrUpdate(predecessorRoomSummary)
} }
} }
}
} }

View File

@ -23,11 +23,10 @@ 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.query.types import im.vector.matrix.android.internal.database.query.types
import im.vector.matrix.android.internal.di.SessionDatabase import im.vector.matrix.android.internal.di.SessionDatabase
import im.vector.matrix.android.internal.task.TaskExecutor
import im.vector.matrix.android.internal.task.configureWith
import io.realm.OrderedCollectionChangeSet import io.realm.OrderedCollectionChangeSet
import io.realm.RealmConfiguration import io.realm.RealmConfiguration
import io.realm.RealmResults import io.realm.RealmResults
import kotlinx.coroutines.launch
import timber.log.Timber import timber.log.Timber
import javax.inject.Inject import javax.inject.Inject
@ -36,8 +35,7 @@ import javax.inject.Inject
* As it will actually delete the content, it should be called last in the list of listener. * As it will actually delete the content, it should be called last in the list of listener.
*/ */
internal class EventsPruner @Inject constructor(@SessionDatabase realmConfiguration: RealmConfiguration, internal class EventsPruner @Inject constructor(@SessionDatabase realmConfiguration: RealmConfiguration,
private val pruneEventTask: PruneEventTask, private val pruneEventTask: PruneEventTask) :
private val taskExecutor: TaskExecutor) :
RealmLiveEntityObserver<EventEntity>(realmConfiguration) { RealmLiveEntityObserver<EventEntity>(realmConfiguration) {
override val query = Monarchy.Query<EventEntity> { EventEntity.types(it, listOf(EventType.REDACTION)) } override val query = Monarchy.Query<EventEntity> { EventEntity.types(it, listOf(EventType.REDACTION)) }
@ -50,7 +48,9 @@ internal class EventsPruner @Inject constructor(@SessionDatabase realmConfigurat
.mapNotNull { results[it]?.asDomain() } .mapNotNull { results[it]?.asDomain() }
.toList() .toList()
observerScope.launch {
val params = PruneEventTask.Params(insertedDomains) val params = PruneEventTask.Params(insertedDomains)
pruneEventTask.configureWith(params).executeBy(taskExecutor) pruneEventTask.execute(params)
}
} }
} }

View File

@ -23,6 +23,7 @@ import im.vector.matrix.android.api.session.events.model.toModel
import im.vector.matrix.android.api.session.room.model.VersioningState import im.vector.matrix.android.api.session.room.model.VersioningState
import im.vector.matrix.android.api.session.room.model.tombstone.RoomTombstoneContent import im.vector.matrix.android.api.session.room.model.tombstone.RoomTombstoneContent
import im.vector.matrix.android.internal.database.RealmLiveEntityObserver import im.vector.matrix.android.internal.database.RealmLiveEntityObserver
import im.vector.matrix.android.internal.database.awaitTransaction
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.RoomSummaryEntity import im.vector.matrix.android.internal.database.model.RoomSummaryEntity
@ -30,9 +31,9 @@ import im.vector.matrix.android.internal.database.query.types
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 io.realm.OrderedCollectionChangeSet import io.realm.OrderedCollectionChangeSet
import io.realm.Realm
import io.realm.RealmConfiguration import io.realm.RealmConfiguration
import io.realm.RealmResults import io.realm.RealmResults
import kotlinx.coroutines.launch
import javax.inject.Inject import javax.inject.Inject
internal class RoomTombstoneEventLiveObserver @Inject constructor(@SessionDatabase internal class RoomTombstoneEventLiveObserver @Inject constructor(@SessionDatabase
@ -51,12 +52,13 @@ internal class RoomTombstoneEventLiveObserver @Inject constructor(@SessionDataba
} }
.toList() .toList()
.also { .also {
observerScope.launch {
handleRoomTombstoneEvents(it) handleRoomTombstoneEvents(it)
} }
} }
}
private fun handleRoomTombstoneEvents(tombstoneEvents: List<Event>) = Realm.getInstance(realmConfiguration).use { private suspend fun handleRoomTombstoneEvents(tombstoneEvents: List<Event>) = awaitTransaction(realmConfiguration) { realm ->
it.executeTransactionAsync { realm ->
for (event in tombstoneEvents) { for (event in tombstoneEvents) {
if (event.roomId == null) continue if (event.roomId == null) continue
val createRoomContent = event.getClearContent().toModel<RoomTombstoneContent>() val createRoomContent = event.getClearContent().toModel<RoomTombstoneContent>()
@ -70,5 +72,4 @@ internal class RoomTombstoneEventLiveObserver @Inject constructor(@SessionDataba
realm.insertOrUpdate(predecessorRoomSummary) realm.insertOrUpdate(predecessorRoomSummary)
} }
} }
}
} }

View File

@ -95,7 +95,6 @@ internal class UserAccountDataSyncHandler @Inject constructor(private val monarc
} }
} }
private fun handlePushRules(realm: Realm, userAccountDataPushRules: UserAccountDataPushRules) { private fun handlePushRules(realm: Realm, userAccountDataPushRules: UserAccountDataPushRules) {
val pushRules = userAccountDataPushRules.content val pushRules = userAccountDataPushRules.content
realm.where(PushRulesEntity::class.java) realm.where(PushRulesEntity::class.java)

View File

@ -20,7 +20,6 @@ import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData import androidx.lifecycle.MutableLiveData
import com.squareup.moshi.JsonEncodingException import com.squareup.moshi.JsonEncodingException
import im.vector.matrix.android.api.failure.Failure import im.vector.matrix.android.api.failure.Failure
import im.vector.matrix.android.api.failure.MatrixError
import im.vector.matrix.android.api.failure.isTokenError import im.vector.matrix.android.api.failure.isTokenError
import im.vector.matrix.android.api.session.sync.SyncState import im.vector.matrix.android.api.session.sync.SyncState
import im.vector.matrix.android.internal.network.NetworkConnectivityChecker import im.vector.matrix.android.internal.network.NetworkConnectivityChecker