Fix some cases of rich reply rendering while/after fetching event

Change-Id: Id940df5c838ac962f28f7b02bb7dfdb2967d8a28
This commit is contained in:
SpiritCroc 2022-11-22 12:52:10 +01:00
parent 437d2815f4
commit 772ff30045
1 changed files with 12 additions and 4 deletions

View File

@ -90,6 +90,8 @@ class ReplyPreviewRetriever(
private val lookedUpEvents = mutableMapOf<String, String>() private val lookedUpEvents = mutableMapOf<String, String>()
// Timestamps of allowed server requests for individual events, to not spam server with the same request // Timestamps of allowed server requests for individual events, to not spam server with the same request
private val serverRequests = mutableMapOf<String, Long>() private val serverRequests = mutableMapOf<String, Long>()
// eventToRetrieveId-specific locking
private val retrieveEventLocks = mutableMapOf<String, Any>()
fun invalidateEventsFromSnapshot(snapshot: List<TimelineEvent>) { fun invalidateEventsFromSnapshot(snapshot: List<TimelineEvent>) {
val snapshotEvents = snapshot.associateBy { it.eventId } val snapshotEvents = snapshot.associateBy { it.eventId }
@ -141,6 +143,9 @@ class ReplyPreviewRetriever(
} }
}?.let { eventIdToRetrieve -> }?.let { eventIdToRetrieve ->
coroutineScope.launch(Dispatchers.IO) { coroutineScope.launch(Dispatchers.IO) {
val retrieveEventLock = synchronized(retrieveEventLocks) {
retrieveEventLocks.getOrPut(eventIdToRetrieve) { eventIdToRetrieve }
}
runCatching { runCatching {
// Don't spam the server too often if it doesn't know the event // Don't spam the server too often if it doesn't know the event
val mayAskServerForEvent = synchronized(serverRequests) { val mayAskServerForEvent = synchronized(serverRequests) {
@ -153,10 +158,13 @@ class ReplyPreviewRetriever(
} }
} }
if (DEBUG) Timber.i("REPLY HANDLING AFTER ${System.currentTimeMillis() - now} for $eventId / $eventIdToRetrieve, may ask: $mayAskServerForEvent")// TODO remove if (DEBUG) Timber.i("REPLY HANDLING AFTER ${System.currentTimeMillis() - now} for $eventId / $eventIdToRetrieve, may ask: $mayAskServerForEvent")// TODO remove
if (mayAskServerForEvent) { // Synchronize, so that we await a pending server fetch if necessary
session.getRoom(roomId)?.timelineService()?.getOrFetchAndPersistTimelineEventBlocking(eventIdToRetrieve) synchronized(retrieveEventLock) {
} else { if (mayAskServerForEvent) {
session.getRoom(roomId)?.getTimelineEvent(eventIdToRetrieve) session.getRoom(roomId)?.timelineService()?.getOrFetchAndPersistTimelineEventBlocking(eventIdToRetrieve)
} else {
session.getRoom(roomId)?.getTimelineEvent(eventIdToRetrieve)
}
}?.apply { }?.apply {
// We need to check encryption // We need to check encryption
val repliedToEvent = root // TODO what if rendered event is not root, i.e. root.eventId != getLatestEventId()? (we currently just use the initial event in this case, better than nothing) val repliedToEvent = root // TODO what if rendered event is not root, i.e. root.eventId != getLatestEventId()? (we currently just use the initial event in this case, better than nothing)