Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix missing/swapped/duplicated messages due to wrong TimelineChunk modifications or insertions #5528

Merged
merged 4 commits into from
May 31, 2022

Conversation

SpiritCroc
Copy link
Contributor

@SpiritCroc SpiritCroc commented Mar 13, 2022

I was observing cases where builtEvents[modificationIndex] was not
having the same eventId as the udpatedEntity in handleDatabaseChangeSet().

In particular, I observed both cases that

  • there was no item in the list yet with the same eventId as the updated
    one
  • there was an item with the same eventId already in the list, but at a
    different position.

Whenever this happened, the timeline would render missing, duplicated,
or swapped messages in the timeline.

Instead of relying on modificationIndex to be the same for both the
change set and builtEvents, look up the proper index by eventId.

Note: I'm not entirely sure if this is the correct way to fix this.
Is the previously used assumption that displayIndex == modificationIndex something that should hold?
If yes, this PR is likely not the correct fix.
If no, could the insertions in handleDatabaseChangeSet() also be broken, since I'm only addressing modification's indices here?

For insertions, inconsistencies could also occur, if the chunk was not fully loaded yet, so check this as well.

Signed-off-by: Tobias Büttner dev@spiritcroc.de

Type of change

  • Feature
  • Bugfix
  • Technical
  • Other :

Content

Look up indices for event modifications, instead of using the ones from the change set.

Motivation and context

Messages were sometimes showing swapped, duplicated, or missing.

Screenshots / GIFs

Tests

Observe if messages are rendered correctly. I also used following commits to further debug this:

Tested devices

  • Physical
  • Emulator
  • OS version(s): Android 11

Checklist

I was observing cases where builtEvents[modificationIndex] was not
having the same eventId as the udpatedEntity in handleDatabaseChangeSet.

In particular, I observed both cases that
- there was no item in the list yet with the same eventId as the updated
  one
- there was an item with the same eventId already in the list, but at a
  different position.

Whenever this happened, the timeline would render missing, duplicated,
or swapped messages in the timeline.

Instead of relying on the modificationIndex to be the same for both the
change set and builtEvents, look up the proper index by eventId.
@SpiritCroc
Copy link
Contributor Author

Example of what this is trying to fix: see missing message 97 with displayIndex 353, but duplicated message 98 with displayIndex 354:

Screenshot_20220309-132319_Beeper_dbg

@SpiritCroc
Copy link
Contributor Author

SpiritCroc commented Mar 19, 2022

I think I just observed a case which fits this prediction of mine:

If no, could the insertions in handleDatabaseChangeSet() also be broken, since I'm only addressing modification's indices here?

I.e., I just had a case where the chunk had all events until displayIndex 11 loaded, and then handleDatabaseChangeSet() was called to insert an event at displayIndex 14, leading to a gap (missing messages 12 and 13). Any ideas how to best handle this case?

@SpiritCroc
Copy link
Contributor Author

SpiritCroc commented Mar 21, 2022

I think I just observed a case which fits this prediction of mine:

If no, could the insertions in handleDatabaseChangeSet() also be broken, since I'm only addressing modification's indices here?

I.e., I just had a case where the chunk had all events until displayIndex 11 loaded, and then handleDatabaseChangeSet() was called to insert an event at displayIndex 14, leading to a gap (missing messages 12 and 13). Any ideas how to best handle this case?

ok, found a way to reproduce: just reduce initial loaded chunk size and pagination size, artificially delay chunk loading from code, and open the timeline somewhere in the past to get some slow forwards loading going on. Now if new messages arrive, these are fast-forwarded before the rest of the chunk is loaded, resulting in skipped messages (and preventing the chunk to load the missed messages). Pushing a fix as another commit. Note I was only able to test the case where insertions where at the beginning so far, not sure how test the other case.

@SpiritCroc SpiritCroc changed the title Fix modifying the wrong events in TimelineChunk Fix missing/swapped/duplicated messages due to wrong TimelineChunk modifications or insertions Mar 21, 2022
@bmarty bmarty added the Z-Community-PR Issue is solved by a community member's PR label Apr 6, 2022
@bmarty
Copy link
Member

bmarty commented Apr 6, 2022

Thanks for the PR. I defer to @ganfra to review it.

@bmarty bmarty requested a review from ganfra April 6, 2022 16:09
Copy link
Contributor

@ganfra ganfra left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM! Probably caused by using coroutines...
Hopefully this won't degrade performance as you need to lookup.

Can you just fix the lint error?

// Check consistency to item before insertions
if (range.startIndex > 0) {
val firstInsertion = results[range.startIndex]!!
val lastBeforeInsertion = builtEvents[range.startIndex - 1]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If there is no built event yet, this could crash

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is builtEvents.isNotEmpty() in line 435

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh yeah; I'm still wandering if we should try to fix the underneath issue here instead of doing some weird checks :/

@bmarty
Copy link
Member

bmarty commented May 11, 2022

@ganfra can we merge this PR?

@bmarty bmarty requested review from a team and ariskotsomitopoulos and removed request for a team May 11, 2022 17:09
Copy link
Contributor

@ariskotsomitopoulos ariskotsomitopoulos left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I didn't test the logic in the code. Just a minor comment

if (builtEvents.isNotEmpty()) {
// Check consistency to item before insertions
if (range.startIndex > 0) {
val firstInsertion = results[range.startIndex]!!
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would avoid !! even if we are sure it cannot be null

@bmarty bmarty merged commit 8e709db into element-hq:develop May 31, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Z-Community-PR Issue is solved by a community member's PR
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants