mirror of
https://github.com/SchildiChat/SchildiChat-android.git
synced 2025-03-15 18:59:12 +03:00
[TMP] Add some debugging to detect timeline inconsistencies
Note: may affect performance a little when loading the timeline, so better revert when we are confident we have fixed the issue. Change-Id: Ic4d31e47948984371a02ce51af7a8d56cb120234
This commit is contained in:
parent
a132ee22cb
commit
7bfd3c8dca
2 changed files with 40 additions and 3 deletions
|
@ -296,6 +296,10 @@ internal class DefaultTimeline(private val roomId: String,
|
|||
private suspend fun postSnapshot() {
|
||||
val snapshot = strategy.buildSnapshot()
|
||||
Timber.v("Post snapshot of ${snapshot.size} events")
|
||||
// Async debugging to not slow down things
|
||||
timelineScope.launch(coroutineDispatchers.computation) {
|
||||
checkTimelineConsistency("DefaultTimeline.postSnapshot", snapshot)
|
||||
}
|
||||
withContext(coroutineDispatchers.main) {
|
||||
listeners.forEach {
|
||||
tryOrNull { it.onTimelineUpdated(snapshot) }
|
||||
|
@ -383,3 +387,32 @@ internal class DefaultTimeline(private val roomId: String,
|
|||
initialEventIdOffset = offset
|
||||
}
|
||||
}
|
||||
|
||||
fun checkTimelineConsistency(location: String, events: List<TimelineEvent>) {
|
||||
Timber.d("Check timeline consistency from $location for ${events.size} events")
|
||||
try {
|
||||
// Note that the "previous" event is actually newer than the currently looked at event,
|
||||
// since the list is ordered from new to old
|
||||
var prev: TimelineEvent? = null
|
||||
for (i in events.indices) {
|
||||
val event = events[i]
|
||||
if (prev != null) {
|
||||
if (prev.eventId == event.eventId) {
|
||||
// This should never happen in a bug-free world, as far as I'm aware
|
||||
Timber.e("Timeline inconsistency found at $location, $i/${events.size}: double event ${event.eventId}")
|
||||
} else if (prev.displayIndex != event.displayIndex + 1 &&
|
||||
// Jumps from -1 to 1 seem to be normal, have only seen index 0 for local echos yet
|
||||
(prev.displayIndex != 1 || event.displayIndex != -1)) {
|
||||
// Note that jumps in either direction may be normal for some scenarios:
|
||||
// - Events between two chunks lead to a new indexing, so one may start at 1, or even something negative.
|
||||
// - The list may omit unsupported events (I guess?), thus causing gaps in the indices.
|
||||
Timber.w("Possible timeline inconsistency found at $location, $i/${events.size}: ${event.displayIndex}->${prev.displayIndex}, ${event.eventId} -> ${prev.eventId}")
|
||||
}
|
||||
}
|
||||
prev = event
|
||||
}
|
||||
Timber.d("Done check timeline consistency from $location")
|
||||
} catch (t: Throwable) {
|
||||
Timber.e("Failed check timeline consistency from $location", t)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -119,6 +119,7 @@ internal class TimelineChunk(private val chunkEntity: ChunkEntity,
|
|||
val nextEvents = nextChunk?.builtItems(includesNext = true, includesPrev = false).orEmpty()
|
||||
deepBuiltItems.addAll(nextEvents)
|
||||
}
|
||||
checkTimelineConsistency("TimelineChunk.builtItems", builtEvents)
|
||||
deepBuiltItems.addAll(builtEvents)
|
||||
if (includesPrev) {
|
||||
val prevEvents = prevChunk?.builtItems(includesNext = false, includesPrev = true).orEmpty()
|
||||
|
@ -294,6 +295,8 @@ internal class TimelineChunk(private val chunkEntity: ChunkEntity,
|
|||
.offsets(direction, count, displayIndex)
|
||||
.findAll()
|
||||
.orEmpty()
|
||||
val builtTimelineEvents = timelineEvents.map { it.buildAndDecryptIfNeeded() }
|
||||
checkTimelineConsistency("TimelineChunk.loadFromStorage-raw-query", builtTimelineEvents)
|
||||
|
||||
if (timelineEvents.isEmpty()) return LoadedFromStorage()
|
||||
// Disabled due to the new fallback
|
||||
|
@ -303,9 +306,10 @@ internal class TimelineChunk(private val chunkEntity: ChunkEntity,
|
|||
if (direction == Timeline.Direction.FORWARDS) {
|
||||
builtEventsIndexes.entries.forEach { it.setValue(it.value + timelineEvents.size) }
|
||||
}
|
||||
timelineEvents
|
||||
.mapIndexed { index, timelineEventEntity ->
|
||||
val timelineEvent = timelineEventEntity.buildAndDecryptIfNeeded()
|
||||
//timelineEvents
|
||||
builtTimelineEvents
|
||||
.mapIndexed { index, timelineEvent -> // timelineEventEntity ->
|
||||
//val timelineEvent = timelineEventEntity.buildAndDecryptIfNeeded()
|
||||
if (timelineEvent.root.type == EventType.STATE_ROOM_CREATE) {
|
||||
isLastBackward.set(true)
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue