Skip to content

fix(event cache): don't remove a gap when it's the only chunk in memory #4779

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

Merged
merged 7 commits into from
Mar 11, 2025

Conversation

bnjbvr
Copy link
Member

@bnjbvr bnjbvr commented Mar 10, 2025

See the commit messages for more explanations. This makes the event cache much more stable for multiverse, by addressing three issues:

Bugs found with multiverse.

Fixes #4785.
Fixes #4784.

Part of #3280.

bnjbvr added 2 commits March 10, 2025 17:17
So we know which room some logs messages correspond to.
`.not()` is useful in assertions, at best, but using it where `!` would
suffice is a bad code smell.
Copy link

codecov bot commented Mar 10, 2025

Codecov Report

Attention: Patch coverage is 97.05882% with 1 line in your changes missing coverage. Please review.

Project coverage is 86.34%. Comparing base (b5c4fe3) to head (b60736c).
Report is 30 commits behind head on main.

Files with missing lines Patch % Lines
crates/matrix-sdk/src/event_cache/mod.rs 50.00% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #4779      +/-   ##
==========================================
- Coverage   86.34%   86.34%   -0.01%     
==========================================
  Files         291      291              
  Lines       34233    34245      +12     
==========================================
+ Hits        29560    29570      +10     
- Misses       4673     4675       +2     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@bnjbvr bnjbvr force-pushed the bnjbvr/bug-fixing-extraordinaire branch from cb4bca7 to c812f0b Compare March 11, 2025 11:53
@bnjbvr bnjbvr marked this pull request as ready for review March 11, 2025 11:54
@bnjbvr bnjbvr requested a review from a team as a code owner March 11, 2025 11:54
@bnjbvr bnjbvr requested review from Hywan and removed request for a team March 11, 2025 11:54
@bnjbvr bnjbvr force-pushed the bnjbvr/bug-fixing-extraordinaire branch from c812f0b to 443bb96 Compare March 11, 2025 12:04
Copy link
Member

@Hywan Hywan left a comment

Choose a reason for hiding this comment

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

Excellent, thanks for the bug fixes!

// Replace the gap with the events we just deduplicated.
room_events.replace_gap_at(reversed_events.clone(), gap_id)
.expect("gap_identifier is a valid chunk id we read previously")
assert!(events.is_empty());
Copy link
Member

Choose a reason for hiding this comment

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

Shouldn't it be reversed_events for the sake of clarity?

Copy link
Member Author

Choose a reason for hiding this comment

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

both are the same, right?

Copy link
Member Author

Choose a reason for hiding this comment

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

you're right it's better 👍

it.next().is_none()
};

let next_pos = if events.is_empty() && !has_only_one_chunk {
Copy link
Member

Choose a reason for hiding this comment

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

👍

@@ -1915,6 +1915,27 @@ mod tests {
let chunks = store.load_all_chunks(room_id).await.unwrap();
assert!(chunks.is_empty());

// Check that cascading worked. Yes, sqlite, I doubt you.
Copy link
Member

Choose a reason for hiding this comment

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

How dare you?

// enabled on a per-connection basis. Execute it every time we try to get a
// connection, since we can't guarantee a previous connection did
// enabled it before.
connection.execute_batch("PRAGMA foreign_keys = ON;").await?;
Copy link
Member

Choose a reason for hiding this comment

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

👍

})
{
if user_ids != prev_user_ids {
self.ignore_user_list_changes.set(user_ids);
Copy link
Member

Choose a reason for hiding this comment

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

It may be a good use case for update_if here, though it's not blocking the approval of this patch.

Copy link
Member Author

Choose a reason for hiding this comment

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

think update_if would trigger an update the first time it's set to a non default value, right? or we'd need to initialize the ignore_user_list_changes with an initial value without having it trigger, or something? might be nice actually, but yeah, follow up

bnjbvr added 5 commits March 11, 2025 14:44
… chunk in memory

A linked chunk never wants to be empty. However, after a limited gap
that doesn't contain events, it may be shrunk to the latest chunk that's
a gap.

If later we decide to remove the gap (because it's been resolved with no
events), then we would try to remove the last chunk, which is not
correct.

Ideally, we'd keep an events chunk around; but if we have an events
chunk *before* a gap, that may look like missing events to the user, at
least until the gap has been resolved.

The fix to this problem is to *not* optimize / remove the gap, if it's
the only chunk kept in memory. This was only a memory optimization, but
it's not absolutely required per se.
As opposed to WAL mode, foreign keys must be enabled for each database
connection, according to
https://www.sqlite.org/foreignkeys.html#fk_enable

Unfortunately, we can't track which connection objects have already
executed the pragma, so the safer we can do is enable it everytime we
try to acquire a connection from the pool.

Fixes #4785.
@bnjbvr bnjbvr force-pushed the bnjbvr/bug-fixing-extraordinaire branch from 443bb96 to b60736c Compare March 11, 2025 13:44
@bnjbvr bnjbvr enabled auto-merge (rebase) March 11, 2025 13:45
@bnjbvr bnjbvr merged commit 7f3308b into main Mar 11, 2025
43 checks passed
@bnjbvr bnjbvr deleted the bnjbvr/bug-fixing-extraordinaire branch March 11, 2025 14:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
2 participants