Merge pull request #7962 from vector-im/feature/bma/oomRealm

Fix oom crashes.
This commit is contained in:
Benoit Marty 2023-01-19 09:41:58 +01:00 committed by GitHub
commit 2ee51ecc92
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 18 additions and 36 deletions

1
changelog.d/7962.bugfix Normal file
View file

@ -0,0 +1 @@
Fix OOM crashes.

View file

@ -102,7 +102,6 @@ internal class DefaultTimeline(
realm = backgroundRealm,
eventDecryptor = eventDecryptor,
paginationTask = paginationTask,
realmConfiguration = realmConfiguration,
fetchTokenAndPaginateTask = fetchTokenAndPaginateTask,
fetchThreadTimelineTask = fetchThreadTimelineTask,
getContextOfEventTask = getEventTask,

View file

@ -19,7 +19,6 @@ package org.matrix.android.sdk.internal.session.room.timeline
import io.realm.OrderedCollectionChangeSet
import io.realm.OrderedRealmCollectionChangeListener
import io.realm.Realm
import io.realm.RealmConfiguration
import io.realm.RealmResults
import io.realm.kotlin.createObject
import io.realm.kotlin.executeTransactionAwait
@ -97,7 +96,6 @@ internal class LoadTimelineStrategy constructor(
val realm: AtomicReference<Realm>,
val eventDecryptor: TimelineEventDecryptor,
val paginationTask: PaginationTask,
val realmConfiguration: RealmConfiguration,
val fetchThreadTimelineTask: FetchThreadTimelineTask,
val fetchTokenAndPaginateTask: FetchTokenAndPaginateTask,
val getContextOfEventTask: GetContextOfEventTask,
@ -351,7 +349,6 @@ internal class LoadTimelineStrategy constructor(
fetchThreadTimelineTask = dependencies.fetchThreadTimelineTask,
eventDecryptor = dependencies.eventDecryptor,
paginationTask = dependencies.paginationTask,
realmConfiguration = dependencies.realmConfiguration,
fetchTokenAndPaginateTask = dependencies.fetchTokenAndPaginateTask,
timelineEventMapper = dependencies.timelineEventMapper,
uiEchoManager = uiEchoManager,
@ -360,7 +357,6 @@ internal class LoadTimelineStrategy constructor(
initialEventId = mode.originEventId(),
onBuiltEvents = dependencies.onEventsUpdated,
onEventsDeleted = dependencies.onEventsDeleted,
realm = dependencies.realm,
localEchoEventFactory = dependencies.localEchoEventFactory,
decorator = createTimelineEventDecorator()
)

View file

@ -42,12 +42,12 @@ internal class RealmSendingEventsDataSource(
private var roomEntity: RoomEntity? = null
private var sendingTimelineEvents: RealmList<TimelineEventEntity>? = null
private var frozenSendingTimelineEvents: RealmList<TimelineEventEntity>? = null
private var mappedSendingTimelineEvents: List<TimelineEvent> = emptyList()
private val sendingTimelineEventsListener = RealmChangeListener<RealmList<TimelineEventEntity>> { events ->
if (events.isValid) {
uiEchoManager.onSentEventsInDatabase(events.map { it.eventId })
updateFrozenResults(events)
mapSendingEvents(events)
onEventsUpdated(false)
}
}
@ -57,37 +57,29 @@ internal class RealmSendingEventsDataSource(
roomEntity = RoomEntity.where(safeRealm, roomId = roomId).findFirst()
sendingTimelineEvents = roomEntity?.sendingTimelineEvents
sendingTimelineEvents?.addChangeListener(sendingTimelineEventsListener)
updateFrozenResults(sendingTimelineEvents)
mapSendingEvents(sendingTimelineEvents)
}
override fun stop() {
sendingTimelineEvents?.removeChangeListener(sendingTimelineEventsListener)
updateFrozenResults(null)
mapSendingEvents(null)
sendingTimelineEvents = null
roomEntity = null
}
private fun updateFrozenResults(sendingEvents: RealmList<TimelineEventEntity>?) {
// Makes sure to close the previous frozen realm
if (frozenSendingTimelineEvents?.isValid == true) {
frozenSendingTimelineEvents?.realm?.close()
}
frozenSendingTimelineEvents = sendingEvents?.freeze()
private fun mapSendingEvents(sendingEvents: RealmList<TimelineEventEntity>?) {
mappedSendingTimelineEvents = sendingEvents?.map { timelineEventMapper.map(it) }.orEmpty()
}
override fun buildSendingEvents(): List<TimelineEvent> {
val builtSendingEvents = mutableListOf<TimelineEvent>()
uiEchoManager.getInMemorySendingEvents()
.addWithUiEcho(builtSendingEvents)
if (frozenSendingTimelineEvents?.isValid == true) {
frozenSendingTimelineEvents
?.filter { timelineEvent ->
builtSendingEvents.none { it.eventId == timelineEvent.eventId }
}
?.map {
timelineEventMapper.map(it)
}?.addWithUiEcho(builtSendingEvents)
}
mappedSendingTimelineEvents
.filter { timelineEvent ->
builtSendingEvents.none { it.eventId == timelineEvent.eventId }
}
.addWithUiEcho(builtSendingEvents)
return builtSendingEvents
}

View file

@ -18,8 +18,6 @@ package org.matrix.android.sdk.internal.session.room.timeline
import io.realm.OrderedCollectionChangeSet
import io.realm.OrderedRealmCollectionChangeListener
import io.realm.Realm
import io.realm.RealmConfiguration
import io.realm.RealmObjectChangeListener
import io.realm.RealmQuery
import io.realm.RealmResults
@ -48,7 +46,6 @@ import org.matrix.android.sdk.internal.session.sync.handler.room.ThreadsAwarenes
import timber.log.Timber
import java.util.Collections
import java.util.concurrent.atomic.AtomicBoolean
import java.util.concurrent.atomic.AtomicReference
/**
* This is a wrapper around a ChunkEntity in the database.
@ -63,7 +60,6 @@ internal class TimelineChunk(
private val fetchThreadTimelineTask: FetchThreadTimelineTask,
private val eventDecryptor: TimelineEventDecryptor,
private val paginationTask: PaginationTask,
private val realmConfiguration: RealmConfiguration,
private val fetchTokenAndPaginateTask: FetchTokenAndPaginateTask,
private val timelineEventMapper: TimelineEventMapper,
private val uiEchoManager: UIEchoManager?,
@ -72,7 +68,6 @@ internal class TimelineChunk(
private val initialEventId: String?,
private val onBuiltEvents: (Boolean) -> Unit,
private val onEventsDeleted: () -> Unit,
private val realm: AtomicReference<Realm>,
private val decorator: TimelineEventDecorator,
val localEchoEventFactory: LocalEchoEventFactory,
) {
@ -605,7 +600,6 @@ internal class TimelineChunk(
timelineId = timelineId,
eventDecryptor = eventDecryptor,
paginationTask = paginationTask,
realmConfiguration = realmConfiguration,
fetchThreadTimelineTask = fetchThreadTimelineTask,
fetchTokenAndPaginateTask = fetchTokenAndPaginateTask,
timelineEventMapper = timelineEventMapper,
@ -616,7 +610,6 @@ internal class TimelineChunk(
onBuiltEvents = this.onBuiltEvents,
onEventsDeleted = this.onEventsDeleted,
decorator = this.decorator,
realm = realm,
localEchoEventFactory = localEchoEventFactory
)
}

View file

@ -19,9 +19,9 @@ package org.matrix.android.sdk.internal.session.room.timeline.decorator
import org.matrix.android.sdk.api.session.room.timeline.TimelineEvent
import org.matrix.android.sdk.internal.session.room.timeline.UIEchoManager
internal class UiEchoDecorator(private val uiEchoManager: UIEchoManager?) : TimelineEventDecorator {
internal class UiEchoDecorator(private val uiEchoManager: UIEchoManager) : TimelineEventDecorator {
override fun decorate(timelineEvent: TimelineEvent): TimelineEvent {
return uiEchoManager?.decorateEventWithReactionUiEcho(timelineEvent) ?: timelineEvent
return uiEchoManager.decorateEventWithReactionUiEcho(timelineEvent)
}
}

View file

@ -105,7 +105,8 @@ internal class SyncResponsePostTreatmentAggregatorHandler @Inject constructor(
.enqueue()
}
private fun handleUserIdsForCheckingTrustAndAffectedRoomShields(userIdsWithDeviceUpdate: Iterable<String>) {
private fun handleUserIdsForCheckingTrustAndAffectedRoomShields(userIdsWithDeviceUpdate: Collection<String>) {
if (userIdsWithDeviceUpdate.isEmpty()) return
crossSigningService.checkTrustAndAffectedRoomShields(userIdsWithDeviceUpdate.toList())
}
}

View file

@ -797,7 +797,7 @@ class TimelineFragment :
}
// We use a custom layout for this menu item, so we need to set a ClickListener
menu.findItem(R.id.open_matrix_apps)?.let { menuItem ->
menuItem.actionView?.debouncedClicks {
menuItem.actionView?.setOnClickListener {
handleMenuItemSelected(menuItem)
}
}
@ -808,7 +808,7 @@ class TimelineFragment :
// Custom thread notification menu item
menu.findItem(R.id.menu_timeline_thread_list)?.let { menuItem ->
menuItem.actionView?.debouncedClicks {
menuItem.actionView?.setOnClickListener {
handleMenuItemSelected(menuItem)
}
}