Room : load room members is totally off the main thread now

This commit is contained in:
ganfra 2018-12-30 10:53:56 +01:00 committed by ganfra
parent 7c0df91a58
commit fd06606c45
3 changed files with 27 additions and 34 deletions

View File

@ -15,13 +15,11 @@ import im.vector.matrix.android.api.session.room.model.MyMembership
import im.vector.matrix.android.api.session.room.model.RoomSummary
import im.vector.matrix.android.api.util.Cancelable
import im.vector.matrix.android.internal.database.mapper.asDomain
import im.vector.matrix.android.internal.database.model.RoomEntity
import im.vector.matrix.android.internal.database.model.RoomSummaryEntity
import im.vector.matrix.android.internal.database.model.RoomSummaryEntityFields
import im.vector.matrix.android.internal.database.query.where
import im.vector.matrix.android.internal.di.MatrixKoinComponent
import im.vector.matrix.android.internal.session.room.members.LoadRoomMembersTask
import im.vector.matrix.android.internal.session.sync.SyncTokenStore
import im.vector.matrix.android.internal.task.TaskExecutor
import im.vector.matrix.android.internal.task.configureWith
import org.koin.core.parameter.parametersOf
@ -33,7 +31,6 @@ internal data class DefaultRoom(
) : Room, MatrixKoinComponent {

private val loadRoomMembersTask by inject<LoadRoomMembersTask>()
private val syncTokenStore by inject<SyncTokenStore>()
private val monarchy by inject<Monarchy>()
private val timelineHolder by inject<TimelineHolder> { parametersOf(roomId) }
private val sendService by inject<SendService> { parametersOf(roomId) }
@ -55,20 +52,8 @@ internal data class DefaultRoom(
}

override fun loadRoomMembersIfNeeded(): Cancelable {
return if (areAllMembersLoaded()) {
object : Cancelable {}
} else {
val token = syncTokenStore.getLastToken()
val params = LoadRoomMembersTask.Params(roomId, token, Membership.LEAVE)
loadRoomMembersTask.configureWith(params).executeBy(taskExecutor)
}
}

private fun areAllMembersLoaded(): Boolean {
return monarchy
.fetchAllCopiedSync { RoomEntity.where(it, roomId) }
.firstOrNull()
?.areAllMembersLoaded ?: false
val params = LoadRoomMembersTask.Params(roomId, Membership.LEAVE)
return loadRoomMembersTask.configureWith(params).executeBy(taskExecutor)
}



View File

@ -9,13 +9,7 @@ import im.vector.matrix.android.internal.session.room.members.DefaultLoadRoomMem
import im.vector.matrix.android.internal.session.room.members.LoadRoomMembersTask
import im.vector.matrix.android.internal.session.room.members.RoomMemberExtractor
import im.vector.matrix.android.internal.session.room.send.DefaultSendService
import im.vector.matrix.android.internal.session.room.timeline.DefaultGetContextOfEventTask
import im.vector.matrix.android.internal.session.room.timeline.DefaultPaginationTask
import im.vector.matrix.android.internal.session.room.timeline.DefaultTimelineHolder
import im.vector.matrix.android.internal.session.room.timeline.GetContextOfEventTask
import im.vector.matrix.android.internal.session.room.timeline.PaginationTask
import im.vector.matrix.android.internal.session.room.timeline.TimelineBoundaryCallback
import im.vector.matrix.android.internal.session.room.timeline.TokenChunkEventPersistor
import im.vector.matrix.android.internal.session.room.timeline.*
import im.vector.matrix.android.internal.util.PagingRequestHelper
import org.koin.dsl.module.module
import retrofit2.Retrofit
@ -32,7 +26,7 @@ class RoomModule {
}

scope(DefaultSession.SCOPE) {
DefaultLoadRoomMembersTask(get(), get()) as LoadRoomMembersTask
DefaultLoadRoomMembersTask(get(), get(), get()) as LoadRoomMembersTask
}

scope(DefaultSession.SCOPE) {

View File

@ -3,33 +3,40 @@ package im.vector.matrix.android.internal.session.room.members
import arrow.core.Try
import com.zhuinden.monarchy.Monarchy
import im.vector.matrix.android.api.session.room.model.Membership
import im.vector.matrix.android.internal.task.Task
import im.vector.matrix.android.internal.database.helper.addStateEvents
import im.vector.matrix.android.internal.database.model.RoomEntity
import im.vector.matrix.android.internal.database.query.where
import im.vector.matrix.android.internal.network.executeRequest
import im.vector.matrix.android.internal.session.room.RoomAPI
import im.vector.matrix.android.internal.session.sync.SyncTokenStore
import im.vector.matrix.android.internal.task.Task
import im.vector.matrix.android.internal.util.tryTransactionSync

internal interface LoadRoomMembersTask : Task<LoadRoomMembersTask.Params, Boolean> {

data class Params(
val roomId: String,
val streamToken: String?,
val excludeMembership: Membership? = null
)
}

internal class DefaultLoadRoomMembersTask(private val roomAPI: RoomAPI,
private val monarchy: Monarchy
private val monarchy: Monarchy,
private val syncTokenStore: SyncTokenStore
) : LoadRoomMembersTask {

override fun execute(params: LoadRoomMembersTask.Params): Try<Boolean> {
return executeRequest<RoomMembersResponse> {
apiCall = roomAPI.getMembers(params.roomId, null, null, params.excludeMembership?.value)
}.flatMap { response ->
insertInDb(response, params.roomId)
}.map { true }
return if (areAllMembersAlreadyLoaded(params.roomId)) {
Try.just(true)
} else {
//TODO use this token
val lastToken = syncTokenStore.getLastToken()
executeRequest<RoomMembersResponse> {
apiCall = roomAPI.getMembers(params.roomId, null, null, params.excludeMembership?.value)
}.flatMap { response ->
insertInDb(response, params.roomId)
}.map { true }
}
}

private fun insertInDb(response: RoomMembersResponse, roomId: String): Try<RoomMembersResponse> {
@ -37,7 +44,7 @@ internal class DefaultLoadRoomMembersTask(private val roomAPI: RoomAPI,
.tryTransactionSync { realm ->
// We ignore all the already known members
val roomEntity = RoomEntity.where(realm, roomId).findFirst()
?: throw IllegalStateException("You shouldn't use this method without a room")
?: throw IllegalStateException("You shouldn't use this method without a room")

val roomMembers = RoomMembers(realm, roomId).getLoaded()
val eventsToInsert = response.roomMemberEvents.filter { !roomMembers.containsKey(it.stateKey) }
@ -48,4 +55,11 @@ internal class DefaultLoadRoomMembersTask(private val roomAPI: RoomAPI,
.map { response }
}

private fun areAllMembersAlreadyLoaded(roomId: String): Boolean {
return monarchy
.fetchAllCopiedSync { RoomEntity.where(it, roomId) }
.firstOrNull()
?.areAllMembersLoaded ?: false
}

}