Merge pull request #4928 from vector-im/feature/aris/stuck_local_echo_issue_516
Potential fix stuck local echo events at the bottom of the screen
This commit is contained in:
commit
5095514ecd
|
@ -0,0 +1 @@
|
||||||
|
Fix for stuck local event messages at the bottom of the screen
|
|
@ -129,6 +129,8 @@ internal class RoomSyncHandler @Inject constructor(private val readReceiptHandle
|
||||||
} else {
|
} else {
|
||||||
handlingStrategy.data.mapWithProgress(reporter, InitSyncStep.ImportingAccountJoinedRooms, 0.6f) {
|
handlingStrategy.data.mapWithProgress(reporter, InitSyncStep.ImportingAccountJoinedRooms, 0.6f) {
|
||||||
handleJoinedRoom(realm, it.key, it.value, insertType, syncLocalTimeStampMillis, aggregator)
|
handleJoinedRoom(realm, it.key, it.value, insertType, syncLocalTimeStampMillis, aggregator)
|
||||||
|
}.also {
|
||||||
|
fixStuckLocalEcho(it)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -478,4 +480,47 @@ internal class RoomSyncHandler @Inject constructor(private val readReceiptHandle
|
||||||
|
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* There are multiple issues like #516 that report stuck local echo events
|
||||||
|
* at the bottom of each room timeline.
|
||||||
|
*
|
||||||
|
* That can happen when a message is SENT but not received back from the /sync.
|
||||||
|
* Until now we use unsignedData.transactionId to determine whether or not the local
|
||||||
|
* event should be deleted on every /sync. However, this is partially correct, lets have a look
|
||||||
|
* at the following scenario:
|
||||||
|
*
|
||||||
|
* [There is no Internet connection] --> [10 Messages are sent] --> [The 10 messages are in the queue] -->
|
||||||
|
* [Internet comes back for 1 second] --> [3 messages are sent] --> [Internet drops again] -->
|
||||||
|
* [No /sync response is triggered | home server can even replied with /sync but never arrived while we are offline]
|
||||||
|
*
|
||||||
|
* So the state until now is that we have 7 pending events to send and 3 sent but not received them back from /sync
|
||||||
|
* Subsequently, those 3 local messages will not be deleted while there is no transactionId from the /sync
|
||||||
|
*
|
||||||
|
* lets continue:
|
||||||
|
* [Now lets assume that in the same room another user sent 15 events] -->
|
||||||
|
* [We are finally back online!] -->
|
||||||
|
* [We will receive the 10 latest events for the room and of course sent the pending 7 messages] -->
|
||||||
|
* Now /sync response will NOT contain the 3 local messages so our events will stuck in the device.
|
||||||
|
*
|
||||||
|
* Someone can say, yes but it will come with the rooms/{roomId}/messages while paginating,
|
||||||
|
* so the problem will be solved. No that is not the case for two reasons:
|
||||||
|
* 1. rooms/{roomId}/messages response do not contain the unsignedData.transactionId so we cannot know which event
|
||||||
|
* to delete
|
||||||
|
* 2. even if transactionId was there, currently we are not deleting it from the pagination
|
||||||
|
*
|
||||||
|
* ---------------------------------------------------------------------------------------------
|
||||||
|
* While we cannot know when a specific event arrived from the pagination (no transactionId included), after each room /sync
|
||||||
|
* we clear all SENT events, and we are sure that we will receive it from /sync or pagination
|
||||||
|
*/
|
||||||
|
private fun fixStuckLocalEcho(rooms: List<RoomEntity>) {
|
||||||
|
rooms.forEach { roomEntity ->
|
||||||
|
roomEntity.sendingTimelineEvents.filter { timelineEvent ->
|
||||||
|
timelineEvent.root?.sendState == SendState.SENT
|
||||||
|
}.forEach {
|
||||||
|
roomEntity.sendingTimelineEvents.remove(it)
|
||||||
|
it.deleteOnCascade(true)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue