Skip to content

Conversation

@bnjbvr
Copy link
Member

@bnjbvr bnjbvr commented Sep 1, 2025

This adds support for:

  • msc4308 sliding sync extension: receiving new changes to thread subscriptions over sync, as well as the prev_batch token that indicates if there are more subscriptions to catch up with the companion endpoint.
  • saving such catchup tokens in the state store
  • automatically catch up for extra thread subscriptions in a background task
  • in Room::load_or_fetch_thread_subscriptions(), use network if we haven't caught up yet, or the local store only, if we have.

I've tested this in isolation, with a few sliding sync tests (using the MatrixMockServer; this adds quite a bit of code to it, expanding the PR's size), as well as against the Synapse impl from element-hq/synapse#18695, and it works great in both cases.

Fixes #5038.

@bnjbvr bnjbvr requested a review from a team as a code owner September 1, 2025 15:02
@bnjbvr bnjbvr requested review from poljar and removed request for a team September 1, 2025 15:02
@codecov
Copy link

codecov bot commented Sep 1, 2025

Codecov Report

❌ Patch coverage is 86.13139% with 38 lines in your changes missing coverage. Please review.
✅ Project coverage is 88.71%. Comparing base (15c46b5) to head (8e6b0d5).
⚠️ Report is 19 commits behind head on main.
✅ All tests successful. No failed tests found.

Files with missing lines Patch % Lines
...ates/matrix-sdk/src/client/thread_subscriptions.rs 86.71% 8 Missing and 11 partials ⚠️
crates/matrix-sdk-sqlite/src/state_store.rs 0.00% 8 Missing and 1 partial ⚠️
crates/matrix-sdk/src/sliding_sync/builder.rs 61.53% 5 Missing ⚠️
crates/matrix-sdk/src/room/mod.rs 86.66% 1 Missing and 1 partial ⚠️
crates/matrix-sdk/src/sliding_sync/client.rs 88.23% 0 Missing and 2 partials ⚠️
crates/matrix-sdk-base/src/store/traits.rs 80.00% 0 Missing and 1 partial ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #5604      +/-   ##
==========================================
- Coverage   88.72%   88.71%   -0.01%     
==========================================
  Files         345      346       +1     
  Lines       97880    98146     +266     
  Branches    97880    98146     +266     
==========================================
+ Hits        86847    87075     +228     
- Misses       6754     6775      +21     
- Partials     4279     4296      +17     

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

@codspeed-hq
Copy link

codspeed-hq bot commented Sep 1, 2025

CodSpeed Performance Report

Merging #5604 will not alter performance

Comparing bnjbvr/msc4308-sliding-sync (8e6b0d5) with main (ea59bc8)

Summary

✅ 49 untouched benchmarks

Copy link
Contributor

@poljar poljar left a comment

Choose a reason for hiding this comment

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

Alright, a couple of changes needed here.

/// These tokens are created when the client receives some thread subscriptions
/// from sync, but the sync indicates that there are more thread subscriptions
/// available on the server. In this case, it's expected that the client will
/// call the MSC4308 companion endpoint to catch up (back-paginate) on previous
Copy link
Contributor

Choose a reason for hiding this comment

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

Linky please on the MSC.

Comment on lines 190 to 243
// Take into account the new unsubscriptions.
for (room_id, room_map) in unsubscribed {
for (event_id, thread_sub) in room_map {
client
.state_store()
.upsert_thread_subscription(
&room_id,
&event_id,
StoredThreadSubscription {
status: ThreadSubscriptionStatus::Unsubscribed,
bump_stamp: Some(thread_sub.bump_stamp.into()),
},
)
.await?;
}
}

// Take into account the new subscriptions.
for (room_id, room_map) in subscribed {
for (event_id, thread_sub) in room_map {
client
.state_store()
.upsert_thread_subscription(
&room_id,
&event_id,
StoredThreadSubscription {
status: ThreadSubscriptionStatus::Subscribed {
automatic: thread_sub.automatic,
},
bump_stamp: Some(thread_sub.bump_stamp.into()),
},
)
.await?;
}
}
Copy link
Contributor

Choose a reason for hiding this comment

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

Not for now, but I think it'll make sense to turn this into a bulk API so we don't take a transaction per iteration.

Let's just put this into a issue or into a separate PR.

Comment on lines +231 to +258
async fn lock(&self) -> Option<GuardedStoreAccess> {
let client = self.client.get()?;
let mutex_guard = self.uniq_mutex.clone().lock_owned().await;
Some(GuardedStoreAccess {
_mutex: mutex_guard,
client,
is_outdated: self.is_outdated.clone(),
})
}
Copy link
Contributor

Choose a reason for hiding this comment

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

This lock seems useful, but we're not using it in the part of the code that stores the subscriptions.

Probably not that important since there shouldn't thousands of subscriptions flying in and out, but might be prudent to utilize the lock in more places.


let has_tokens = !tokens.is_empty();

guard.save_catchup_tokens(tokens).await?;
Copy link
Contributor

Choose a reason for hiding this comment

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

Could we return the value for has_tokens in save_catchup_tokens()?

As it is now, we're calculating this flag twice. Once in save_catchup_tokens() and once here.

If we ever change this we'd need to remember to modify two places.

}

/// The background task listening to new catchup tokens, and using them to
/// catch up the thread subscriptions via the msc4308 companion
Copy link
Contributor

Choose a reason for hiding this comment

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

Linky to the MSC.

|| !self.inner.lists.read().await.is_empty()
}

/// Sned a single sliding sync request, and returns the response summary.
Copy link
Contributor

Choose a reason for hiding this comment

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

Send*

Copy link
Contributor

@poljar poljar left a comment

Choose a reason for hiding this comment

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

Well that was fast.

@bnjbvr bnjbvr force-pushed the bnjbvr/msc4308-sliding-sync branch from 89e4062 to 8e6b0d5 Compare September 2, 2025 12:42
@bnjbvr bnjbvr enabled auto-merge (rebase) September 2, 2025 12:43
@bnjbvr bnjbvr merged commit e89ac3d into main Sep 2, 2025
53 checks passed
@bnjbvr bnjbvr deleted the bnjbvr/msc4308-sliding-sync branch September 2, 2025 12:57
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.

Threads: Implement the new participation model API

2 participants