From 3a216759a134e6cf315b5da4e93435b756f0f960 Mon Sep 17 00:00:00 2001 From: ganfra Date: Wed, 29 Jun 2022 11:32:38 +0200 Subject: [PATCH 1/6] LoadRoomMembers: divide by chunk --- .../room/membership/LoadRoomMembersTask.kt | 47 +++++++++++-------- 1 file changed, 27 insertions(+), 20 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 15d0889255..b170a2b6a4 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 @@ -32,6 +32,7 @@ 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.create import org.matrix.android.sdk.internal.database.query.getOrCreate import org.matrix.android.sdk.internal.database.query.where import org.matrix.android.sdk.internal.di.SessionDatabase @@ -43,6 +44,7 @@ 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 org.matrix.android.sdk.internal.util.time.Clock +import timber.log.Timber import java.util.concurrent.TimeUnit import javax.inject.Inject @@ -105,32 +107,37 @@ internal class DefaultLoadRoomMembersTask @Inject constructor( } private suspend fun insertInDb(response: RoomMembersResponse, roomId: String) { + val chunks = response.roomMemberEvents.chunked(500) + chunks.forEach { roomMemberEvents -> + monarchy.awaitTransaction { realm -> + Timber.v("Insert ${roomMemberEvents.size} member events in room $roomId") + // We ignore all the already known members + val now = clock.epochMillis() + for (roomMemberEvent in roomMemberEvents) { + if (roomMemberEvent.eventId == null || roomMemberEvent.stateKey == null || roomMemberEvent.type == null) { + continue + } + val ageLocalTs = roomMemberEvent.unsignedData?.age?.let { now - it } + val eventEntity = roomMemberEvent.toEntity(roomId, SendState.SYNCED, ageLocalTs).copyToRealmOrIgnore(realm, EventInsertType.PAGINATION) + CurrentStateEventEntity.getOrCreate( + realm, + roomId, + roomMemberEvent.stateKey, + roomMemberEvent.type + ).apply { + eventId = roomMemberEvent.eventId + root = eventEntity + } + roomMemberEventHandler.handle(realm, roomId, roomMemberEvent, false) + } + } + } monarchy.awaitTransaction { realm -> - // We ignore all the already known members val roomEntity = RoomEntity.where(realm, roomId).findFirst() ?: realm.createObject(roomId) - val now = clock.epochMillis() - for (roomMemberEvent in response.roomMemberEvents) { - if (roomMemberEvent.eventId == null || roomMemberEvent.stateKey == null || roomMemberEvent.type == null) { - continue - } - val ageLocalTs = roomMemberEvent.unsignedData?.age?.let { now - it } - val eventEntity = roomMemberEvent.toEntity(roomId, SendState.SYNCED, ageLocalTs).copyToRealmOrIgnore(realm, EventInsertType.PAGINATION) - CurrentStateEventEntity.getOrCreate( - realm, - roomId, - roomMemberEvent.stateKey, - roomMemberEvent.type - ).apply { - eventId = roomMemberEvent.eventId - root = eventEntity - } - roomMemberEventHandler.handle(realm, roomId, roomMemberEvent, false) - } roomEntity.membersLoadStatus = RoomMembersLoadStatusType.LOADED roomSummaryUpdater.update(realm, roomId, updateMembers = true) } - if (cryptoSessionInfoProvider.isRoomEncrypted(roomId)) { deviceListManager.onRoomMembersLoadedFor(roomId) } From 63f0cce56141f7b4f366143b6687f80a986322b7 Mon Sep 17 00:00:00 2001 From: ganfra Date: Wed, 29 Jun 2022 11:34:43 +0200 Subject: [PATCH 2/6] LoadRoomMembers: exclude Membership.Leave --- .../session/room/membership/DefaultMembershipService.kt | 2 +- .../sdk/internal/session/room/timeline/DefaultTimeline.kt | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/membership/DefaultMembershipService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/membership/DefaultMembershipService.kt index 005d7f26db..ef89ca33a7 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/membership/DefaultMembershipService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/membership/DefaultMembershipService.kt @@ -58,7 +58,7 @@ internal class DefaultMembershipService @AssistedInject constructor( } override suspend fun loadRoomMembersIfNeeded() { - val params = LoadRoomMembersTask.Params(roomId, Membership.LEAVE) + val params = LoadRoomMembersTask.Params(roomId, excludeMembership = Membership.LEAVE) loadRoomMembersTask.execute(params) } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/timeline/DefaultTimeline.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/timeline/DefaultTimeline.kt index 7795a56cbf..d1eb8794bf 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/timeline/DefaultTimeline.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/timeline/DefaultTimeline.kt @@ -33,6 +33,7 @@ import kotlinx.coroutines.withContext import okhttp3.internal.closeQuietly import org.matrix.android.sdk.api.MatrixCoroutineDispatchers import org.matrix.android.sdk.api.extensions.tryOrNull +import org.matrix.android.sdk.api.session.room.model.Membership import org.matrix.android.sdk.api.session.room.timeline.Timeline import org.matrix.android.sdk.api.session.room.timeline.TimelineEvent import org.matrix.android.sdk.api.session.room.timeline.TimelineSettings @@ -388,7 +389,7 @@ internal class DefaultTimeline( } private suspend fun loadRoomMembersIfNeeded() { - val loadRoomMembersParam = LoadRoomMembersTask.Params(roomId) + val loadRoomMembersParam = LoadRoomMembersTask.Params(roomId, excludeMembership = Membership.LEAVE) try { loadRoomMembersTask.execute(loadRoomMembersParam) } catch (failure: Throwable) { From 61c5bbc444c9eebc889f34efd39d98abb59749fb Mon Sep 17 00:00:00 2001 From: ganfra Date: Wed, 29 Jun 2022 11:35:31 +0200 Subject: [PATCH 3/6] LoadRoomMembers: handle room member event a bit more efficiently --- .../room/membership/RoomMemberEventHandler.kt | 30 ++++++++----------- 1 file changed, 13 insertions(+), 17 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/membership/RoomMemberEventHandler.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/membership/RoomMemberEventHandler.kt index 1e36e9c6da..1f4d53726d 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/membership/RoomMemberEventHandler.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/membership/RoomMemberEventHandler.kt @@ -83,23 +83,19 @@ internal class RoomMemberEventHandler @Inject constructor( userId: String, roomMember: RoomMemberContent ) { - val roomMemberEntity = RoomMemberEntityFactory.create( - roomId, - userId, - roomMember, - // When an update is happening, insertOrUpdate replace existing values with null if they are not provided, - // but we want to preserve presence record value and not replace it with null - getExistingPresenceState(realm, roomId, userId) - ) - realm.insertOrUpdate(roomMemberEntity) - } - - /** - * Get the already existing presence state for a specific user & room in order NOT to be replaced in RoomMemberSummaryEntity - * by NULL value. - */ - private fun getExistingPresenceState(realm: Realm, roomId: String, userId: String): UserPresenceEntity? { - return RoomMemberSummaryEntity.where(realm, roomId, userId).findFirst()?.userPresenceEntity + val existingRoomMemberSummary = RoomMemberSummaryEntity.where(realm, roomId, userId).findFirst() + if (existingRoomMemberSummary != null) { + existingRoomMemberSummary.displayName = roomMember.displayName + existingRoomMemberSummary.avatarUrl = roomMember.avatarUrl + existingRoomMemberSummary.membership = roomMember.membership + } else { + val roomMemberEntity = RoomMemberEntityFactory.create( + roomId, + userId, + roomMember + ) + realm.insert(roomMemberEntity) + } } private fun saveUserEntityLocallyIfNecessary( From 9233007d97becf5f73cc04a3341b175eaf2af324 Mon Sep 17 00:00:00 2001 From: ganfra Date: Wed, 29 Jun 2022 11:37:15 +0200 Subject: [PATCH 4/6] LoadRoomMembers: add changelog --- changelog.d/6394.misc | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelog.d/6394.misc diff --git a/changelog.d/6394.misc b/changelog.d/6394.misc new file mode 100644 index 0000000000..16b4fbf616 --- /dev/null +++ b/changelog.d/6394.misc @@ -0,0 +1 @@ +Let LoadRoomMembersTask insert by chunk to release db. From 7d349bdfc32d539229a8d3c505ae1a4e5430691f Mon Sep 17 00:00:00 2001 From: ganfra Date: Wed, 29 Jun 2022 11:38:15 +0200 Subject: [PATCH 5/6] Cleanup --- .../sdk/internal/session/room/membership/LoadRoomMembersTask.kt | 1 - .../internal/session/room/membership/RoomMemberEventHandler.kt | 1 - 2 files changed, 2 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 b170a2b6a4..b7670499ae 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 @@ -32,7 +32,6 @@ 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.create import org.matrix.android.sdk.internal.database.query.getOrCreate import org.matrix.android.sdk.internal.database.query.where import org.matrix.android.sdk.internal.di.SessionDatabase diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/membership/RoomMemberEventHandler.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/membership/RoomMemberEventHandler.kt index 1f4d53726d..63c23de659 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/membership/RoomMemberEventHandler.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/membership/RoomMemberEventHandler.kt @@ -22,7 +22,6 @@ import org.matrix.android.sdk.api.session.events.model.Event import org.matrix.android.sdk.api.session.events.model.EventType import org.matrix.android.sdk.api.session.room.model.RoomMemberContent import org.matrix.android.sdk.internal.database.model.RoomMemberSummaryEntity -import org.matrix.android.sdk.internal.database.model.presence.UserPresenceEntity import org.matrix.android.sdk.internal.database.query.where import org.matrix.android.sdk.internal.di.UserId import org.matrix.android.sdk.internal.session.events.getFixedRoomMemberContent From b446ceded885f5a93b95fadc40801cb705c7d198 Mon Sep 17 00:00:00 2001 From: ganfra Date: Wed, 29 Jun 2022 19:01:23 +0200 Subject: [PATCH 6/6] LoadRoomMember: fix presence --- .../session/room/membership/RoomMemberEventHandler.kt | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/membership/RoomMemberEventHandler.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/membership/RoomMemberEventHandler.kt index 63c23de659..fd6552525e 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/membership/RoomMemberEventHandler.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/membership/RoomMemberEventHandler.kt @@ -22,6 +22,7 @@ import org.matrix.android.sdk.api.session.events.model.Event import org.matrix.android.sdk.api.session.events.model.EventType import org.matrix.android.sdk.api.session.room.model.RoomMemberContent import org.matrix.android.sdk.internal.database.model.RoomMemberSummaryEntity +import org.matrix.android.sdk.internal.database.model.presence.UserPresenceEntity import org.matrix.android.sdk.internal.database.query.where import org.matrix.android.sdk.internal.di.UserId import org.matrix.android.sdk.internal.session.events.getFixedRoomMemberContent @@ -88,10 +89,12 @@ internal class RoomMemberEventHandler @Inject constructor( existingRoomMemberSummary.avatarUrl = roomMember.avatarUrl existingRoomMemberSummary.membership = roomMember.membership } else { + val presenceEntity = UserPresenceEntity.where(realm, userId).findFirst() val roomMemberEntity = RoomMemberEntityFactory.create( roomId, userId, - roomMember + roomMember, + presenceEntity ) realm.insert(roomMemberEntity) }