Skip to content

feat(sdk): Implement persistent storage for ThreadEventCache#6317

Draft
Hywan wants to merge 22 commits intomatrix-org:mainfrom
Hywan:feat-sdk-event-cache-thread-persistent-storage
Draft

feat(sdk): Implement persistent storage for ThreadEventCache#6317
Hywan wants to merge 22 commits intomatrix-org:mainfrom
Hywan:feat-sdk-event-cache-thread-persistent-storage

Conversation

@Hywan
Copy link
Copy Markdown
Member

@Hywan Hywan commented Mar 19, 2026

This patch implement persistent storage for ThreadEventCache.

This contribution deserves a lot more tests but it will increase the diff size by a lot. The current strategy is to ensure all existing tests are passing. A test with a custom build of multiverse and Element X confirm it works as expected. Another PR will add all the missing tests, along with modifying the test suite of the Event Cache to share many tests between the RoomEventCache and the ThreadEventCache.

This contribution makes it work. However, refactoring is now necessary as similar code exists between RoomEventCache and ThreadEventCache. That's for a next patch.

Best to review one patch at a time. I tried to keep patch as small as possible.



  • I've documented the public API Changes in the appropriate CHANGELOG.md files.
  • This PR was made with the help of AI.

@codspeed-hq
Copy link
Copy Markdown

codspeed-hq bot commented Mar 19, 2026

Merging this PR will not alter performance

✅ 50 untouched benchmarks


Comparing Hywan:feat-sdk-event-cache-thread-persistent-storage (7fe2c70) with main (ec3657d)

Open in CodSpeed

Hywan added 10 commits March 20, 2026 11:38
…adEventCacheState`.

This patch checks if the `EventCacheStoreLock` is dirty when
constructing `LockedThreadEventCacheState`. This patch is the first
step, but it involved a bit of refactoring since `new` is now fallible
and async. It propagates up to the public API which were already
fallible and async fortunately for us: no breaking change.

This patch changes `get_or_reload` to not clone the room ID, the store
etc. every time, but rather only when the `ThreadEventCache` must be
created.
This patch moves the `load_linked_chunk_metadata` function from
`event_cache::caches::room::state` to `event_cache::persistence`. It's
going to be useful for `ThreadEventCache`.
This patch loads the LinkedChunk metadata, in addition to lazy load the
last chunk of the `ThreadEventCache`.
…ded.

This patch updates the `reload` method on the
`ThreadEventCacheStateLockWriteGuard` to shrink to the last chunk from
the store.
…he`.

This patch updates `ThreadEventCacheStateLockWriteGuard::remove_events`
to also remove events from the store (it was only removing events from
the in-memory LinkedChunk prior to this patch).
This patch simply inlines a variable definition to simplify the code.
This patch replaces
`ThreadEventCacheStateLockWriteGuard::filter_duplicate_events` by
`deduplicator::filter_duplicate_events`. First off, this function is
shared between multiple event caches. Second, it deduplicates events
regarding in-memory and in-store state.

The calls to `ThreadEventCacheStateLockWriteGuard::remove_events` have
been updated to pass the duplicated in-store events.
@Hywan Hywan force-pushed the feat-sdk-event-cache-thread-persistent-storage branch from 68340ee to 5a8b3af Compare March 20, 2026 10:41
Hywan added 6 commits March 20, 2026 11:43
This patch forces to use of `use self::s` instead of `use s` to make it
clear it comes from `self`. It clarifies the code here.
This patch makes `RoomEventCacheInner::weak_room`, `state`,
`pagination_batch_token_notifier`, and `shared_pagination_status`
private.
This patch creates the `ThreadEventCacheUpdateSender` à la
`RoomEventCacheUpdateSender` to abstract the sender.

This patch uses `ThreadEventCacheUpdateSender` in
`ThreadEventCacheInner` (new) along with `ThreadEventCacheState`. The
use in the `ThreadEventCacheInner` type is necessary to be able to send
updates without reaching the state (which is behind an async faillible
lock). This is necessary for pagination, see next commit.
This patch adds the ability to paginate in the store for
`ThreadPagination`.
…EventCacheStateLockWriteGuard`.

This patch passes the `prev_batch_token` up to
`ThreadEventCacheStateLockWriteGuard::handle_sync`.
@Hywan Hywan force-pushed the feat-sdk-event-cache-thread-persistent-storage branch 2 times, most recently from 1527d82 to c7692a4 Compare March 23, 2026 16:43
Hywan added 5 commits March 24, 2026 18:38
This patch stops erasing threads when a gap is encountered. Instead, it
will insert gaps as we do for rooms.
This patch renames the `test_thread_can_paginate_evn_if_seen_sync_event`
to `test_thread_contains_its_root_event`. It is what it tests.
This patch replaces the construction of an event by its equivalent in a
variable. The test uses `first_event` and `second_event`, but builds the
“`second_event`” manually for no reason, it's just confusing
…dated.

This patch fixes an invalid behaviour in a thread: when an in-thread
event was redacted, it was removed from the thread. This is inconsistent
regarding in-room event redaction where a redacted event is updated to
its redacted form and the redaction event is added to the timeline. This
patch makes the behaviour consistent by updating the redacted event.

Basically, it replaces `remove_if_present` (deleted) by
`replace_event_if_present` (new).
@Hywan Hywan force-pushed the feat-sdk-event-cache-thread-persistent-storage branch from 942609f to 12a1ef0 Compare March 24, 2026 17:39
@codecov
Copy link
Copy Markdown

codecov bot commented Mar 24, 2026

Codecov Report

❌ Patch coverage is 59.49657% with 177 lines in your changes missing coverage. Please review.
✅ Project coverage is 89.74%. Comparing base (7beda79) to head (7fe2c70).
⚠️ Report is 38 commits behind head on main.
✅ All tests successful. No failed tests found.

Files with missing lines Patch % Lines
.../matrix-sdk/src/event_cache/caches/thread/state.rs 53.28% 66 Missing and 5 partials ⚠️
...ix-sdk/src/event_cache/caches/thread/pagination.rs 47.32% 55 Missing and 4 partials ⚠️
crates/matrix-sdk/src/event_cache/persistence.rs 53.84% 32 Missing and 4 partials ⚠️
...es/matrix-sdk/src/event_cache/caches/thread/mod.rs 84.84% 1 Missing and 4 partials ⚠️
...es/matrix-sdk/src/event_cache/caches/room/state.rs 90.24% 0 Missing and 4 partials ⚠️
...ates/matrix-sdk/src/event_cache/caches/room/mod.rs 50.00% 0 Missing and 1 partial ⚠️
...trix-sdk/src/event_cache/caches/room/pagination.rs 90.00% 0 Missing and 1 partial ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #6317      +/-   ##
==========================================
- Coverage   89.81%   89.74%   -0.07%     
==========================================
  Files         376      377       +1     
  Lines      102614   102793     +179     
  Branches   102614   102793     +179     
==========================================
+ Hits        92163    92254      +91     
- Misses       6871     6959      +88     
  Partials     3580     3580              

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant