From ca4b91a98f3086a4ce167d9942023233e039aa0c Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Fri, 18 Dec 2020 16:38:27 +0100 Subject: [PATCH] Use the new RoomMembersLoadStatusType.LOADING value --- .../room/membership/LoadRoomMembersTask.kt | 48 +++++++++++++++---- 1 file changed, 39 insertions(+), 9 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/membership/LoadRoomMembersTask.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/membership/LoadRoomMembersTask.kt index 69530c5c0e..55dd747fdb 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/membership/LoadRoomMembersTask.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/membership/LoadRoomMembersTask.kt @@ -17,12 +17,19 @@ package org.matrix.android.sdk.internal.session.room.membership import com.zhuinden.monarchy.Monarchy +import io.realm.Realm +import io.realm.kotlin.createObject +import kotlinx.coroutines.TimeoutCancellationException +import org.greenrobot.eventbus.EventBus import org.matrix.android.sdk.api.session.room.model.Membership import org.matrix.android.sdk.api.session.room.send.SendState +import org.matrix.android.sdk.internal.database.awaitNotEmptyResult import org.matrix.android.sdk.internal.database.mapper.toEntity import org.matrix.android.sdk.internal.database.model.CurrentStateEventEntity import org.matrix.android.sdk.internal.database.model.EventInsertType import org.matrix.android.sdk.internal.database.model.RoomEntity +import org.matrix.android.sdk.internal.database.model.RoomEntityFields +import org.matrix.android.sdk.internal.database.model.RoomMembersLoadStatusType import org.matrix.android.sdk.internal.database.query.copyToRealmOrIgnore import org.matrix.android.sdk.internal.database.query.getOrCreate import org.matrix.android.sdk.internal.database.query.where @@ -33,10 +40,7 @@ import org.matrix.android.sdk.internal.session.room.summary.RoomSummaryUpdater import org.matrix.android.sdk.internal.session.sync.SyncTokenStore import org.matrix.android.sdk.internal.task.Task import org.matrix.android.sdk.internal.util.awaitTransaction -import io.realm.Realm -import io.realm.kotlin.createObject -import org.greenrobot.eventbus.EventBus -import org.matrix.android.sdk.internal.database.model.RoomMembersLoadStatusType +import java.util.concurrent.TimeUnit import javax.inject.Inject internal interface LoadRoomMembersTask : Task { @@ -57,9 +61,33 @@ internal class DefaultLoadRoomMembersTask @Inject constructor( ) : LoadRoomMembersTask { override suspend fun execute(params: LoadRoomMembersTask.Params) { - if (areAllMembersAlreadyLoaded(params.roomId)) { - return + when (getRoomMembersLoadStatus(params.roomId)) { + RoomMembersLoadStatusType.NONE -> doRequest(params) + RoomMembersLoadStatusType.LOADING -> waitPreviousRequestToFinish(params) + RoomMembersLoadStatusType.LOADED -> Unit } + } + + private suspend fun waitPreviousRequestToFinish(params: LoadRoomMembersTask.Params) { + try { + awaitNotEmptyResult(monarchy.realmConfiguration, TimeUnit.MINUTES.toMillis(1L)) { realm -> + realm.where(RoomEntity::class.java) + .equalTo(RoomEntityFields.ROOM_ID, params.roomId) + .equalTo(RoomEntityFields.MEMBERS_LOAD_STATUS_STR, RoomMembersLoadStatusType.LOADED.name) + } + } catch (exception: TimeoutCancellationException) { + // Timeout, do the request anyway (?) + doRequest(params) + } + } + + private suspend fun doRequest(params: LoadRoomMembersTask.Params) { + monarchy.awaitTransaction { realm -> + val roomEntity = RoomEntity.where(realm, params.roomId).findFirst() + ?: realm.createObject(params.roomId) + roomEntity.membersLoadStatus = RoomMembersLoadStatusType.LOADING + } + val lastToken = syncTokenStore.getLastToken() val response = executeRequest(eventBus) { apiCall = roomAPI.getMembers(params.roomId, lastToken, null, params.excludeMembership?.value) @@ -90,9 +118,11 @@ internal class DefaultLoadRoomMembersTask @Inject constructor( } } - private fun areAllMembersAlreadyLoaded(roomId: String): Boolean { - return Realm.getInstance(monarchy.realmConfiguration).use { - RoomEntity.where(it, roomId).findFirst()?.membersLoadStatus == RoomMembersLoadStatusType.LOADED + private fun getRoomMembersLoadStatus(roomId: String): RoomMembersLoadStatusType { + var result: RoomMembersLoadStatusType? + Realm.getInstance(monarchy.realmConfiguration).use { + result = RoomEntity.where(it, roomId).findFirst()?.membersLoadStatus } + return result ?: RoomMembersLoadStatusType.NONE } }