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.session.room.model.RoomSummary
import im.vector.matrix.android.api.util.Cancelable import im.vector.matrix.android.api.util.Cancelable
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.RoomEntity
import im.vector.matrix.android.internal.database.model.RoomSummaryEntity 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.model.RoomSummaryEntityFields
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.MatrixKoinComponent 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.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.TaskExecutor
import im.vector.matrix.android.internal.task.configureWith import im.vector.matrix.android.internal.task.configureWith
import org.koin.core.parameter.parametersOf import org.koin.core.parameter.parametersOf
@ -33,7 +31,6 @@ internal data class DefaultRoom(
) : Room, MatrixKoinComponent { ) : Room, MatrixKoinComponent {
private val loadRoomMembersTask by inject<LoadRoomMembersTask>() private val loadRoomMembersTask by inject<LoadRoomMembersTask>()
private val syncTokenStore by inject<SyncTokenStore>()
private val monarchy by inject<Monarchy>() private val monarchy by inject<Monarchy>()
private val timelineHolder by inject<TimelineHolder> { parametersOf(roomId) } private val timelineHolder by inject<TimelineHolder> { parametersOf(roomId) }
private val sendService by inject<SendService> { parametersOf(roomId) } private val sendService by inject<SendService> { parametersOf(roomId) }
@ -55,20 +52,8 @@ internal data class DefaultRoom(
} }
override fun loadRoomMembersIfNeeded(): Cancelable { override fun loadRoomMembersIfNeeded(): Cancelable {
return if (areAllMembersLoaded()) { val params = LoadRoomMembersTask.Params(roomId, Membership.LEAVE)
object : Cancelable {} return loadRoomMembersTask.configureWith(params).executeBy(taskExecutor)
} 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
} }

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.LoadRoomMembersTask
import im.vector.matrix.android.internal.session.room.members.RoomMemberExtractor 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.send.DefaultSendService
import im.vector.matrix.android.internal.session.room.timeline.DefaultGetContextOfEventTask import im.vector.matrix.android.internal.session.room.timeline.*
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.util.PagingRequestHelper import im.vector.matrix.android.internal.util.PagingRequestHelper
import org.koin.dsl.module.module import org.koin.dsl.module.module
import retrofit2.Retrofit import retrofit2.Retrofit
@ -32,7 +26,7 @@ class RoomModule {
} }
scope(DefaultSession.SCOPE) { scope(DefaultSession.SCOPE) {
DefaultLoadRoomMembersTask(get(), get()) as LoadRoomMembersTask DefaultLoadRoomMembersTask(get(), get(), get()) as LoadRoomMembersTask
} }
scope(DefaultSession.SCOPE) { scope(DefaultSession.SCOPE) {

View File

@ -3,33 +3,40 @@ package im.vector.matrix.android.internal.session.room.members
import arrow.core.Try import arrow.core.Try
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.task.Task
import im.vector.matrix.android.internal.database.helper.addStateEvents 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.model.RoomEntity
import im.vector.matrix.android.internal.database.query.where import im.vector.matrix.android.internal.database.query.where
import im.vector.matrix.android.internal.network.executeRequest import im.vector.matrix.android.internal.network.executeRequest
import im.vector.matrix.android.internal.session.room.RoomAPI 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 import im.vector.matrix.android.internal.util.tryTransactionSync
internal interface LoadRoomMembersTask : Task<LoadRoomMembersTask.Params, Boolean> { internal interface LoadRoomMembersTask : Task<LoadRoomMembersTask.Params, Boolean> {
data class Params( data class Params(
val roomId: String, val roomId: String,
val streamToken: String?,
val excludeMembership: Membership? = null val excludeMembership: Membership? = null
) )
} }
internal class DefaultLoadRoomMembersTask(private val roomAPI: RoomAPI, internal class DefaultLoadRoomMembersTask(private val roomAPI: RoomAPI,
private val monarchy: Monarchy private val monarchy: Monarchy,
private val syncTokenStore: SyncTokenStore
) : LoadRoomMembersTask { ) : LoadRoomMembersTask {
override fun execute(params: LoadRoomMembersTask.Params): Try<Boolean> { override fun execute(params: LoadRoomMembersTask.Params): Try<Boolean> {
return executeRequest<RoomMembersResponse> { return if (areAllMembersAlreadyLoaded(params.roomId)) {
apiCall = roomAPI.getMembers(params.roomId, null, null, params.excludeMembership?.value) Try.just(true)
}.flatMap { response -> } else {
insertInDb(response, params.roomId) //TODO use this token
}.map { true } 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> { private fun insertInDb(response: RoomMembersResponse, roomId: String): Try<RoomMembersResponse> {
@ -37,7 +44,7 @@ internal class DefaultLoadRoomMembersTask(private val roomAPI: RoomAPI,
.tryTransactionSync { realm -> .tryTransactionSync { realm ->
// We ignore all the already known members // We ignore all the already known members
val roomEntity = RoomEntity.where(realm, roomId).findFirst() 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 roomMembers = RoomMembers(realm, roomId).getLoaded()
val eventsToInsert = response.roomMemberEvents.filter { !roomMembers.containsKey(it.stateKey) } val eventsToInsert = response.roomMemberEvents.filter { !roomMembers.containsKey(it.stateKey) }
@ -48,4 +55,11 @@ internal class DefaultLoadRoomMembersTask(private val roomAPI: RoomAPI,
.map { response } .map { response }
} }
private fun areAllMembersAlreadyLoaded(roomId: String): Boolean {
return monarchy
.fetchAllCopiedSync { RoomEntity.where(it, roomId) }
.firstOrNull()
?.areAllMembersLoaded ?: false
}
} }