Skip to content

Commit

Permalink
feat: add add_cached_list to SlidingSyncBuilder and SlidingSync (
Browse files Browse the repository at this point in the history
…#1876)

This has slightly drifted from the initial design I thought about in the issue.

Instead of having `build()` be fallible and mutably borrow some substate (namely `BTreeMap<OwnedRoomId, SlidingSyncRoom>`) from `SlidingSync` (that may or may not already exist), I've introduced a new `add_cached_list` method on `SlidingSync` and `SlidingSyncBuilder`. This method hides all the underlying machinery, and injects the room data read from the list cache into the sliding sync room map.

In particular, with these changes:

- any list added with `add_list` **won't** be loaded from/written to the cache storage,
- any list added with `add_cached_list` will be cached, and an attempt to reload it from the cache will be done during this call (hence `async` + `Result`).
- `SlidingSyncBuilder::build()` now only fetches the `SlidingSync` data from the cache (assuming the storage key has been defined), not that of the lists anymore.

Fixes #1737.

Signed-off-by: Benjamin Bouvier <[email protected]>
Co-authored-by: Jonas Platte <[email protected]>
  • Loading branch information
bnjbvr and jplatte authored May 15, 2023
1 parent c404e37 commit 58dbe1e
Show file tree
Hide file tree
Showing 7 changed files with 349 additions and 116 deletions.
24 changes: 24 additions & 0 deletions bindings/matrix-sdk-ffi/src/sliding_sync.rs
Original file line number Diff line number Diff line change
Expand Up @@ -745,6 +745,19 @@ impl SlidingSync {
self.inner.add_list(unwrap_or_clone_arc(list_builder).inner).unwrap();
}

pub fn add_cached_list(
&self,
list_builder: Arc<SlidingSyncListBuilder>,
) -> Result<Option<Arc<SlidingSyncList>>, ClientError> {
RUNTIME.block_on(async move {
Ok(self
.inner
.add_cached_list(list_builder.inner.clone())
.await?
.map(|inner| Arc::new(SlidingSyncList { inner })))
})
}

pub fn reset_lists(&self) -> Result<(), SlidingSyncError> {
self.inner.reset_lists().map_err(Into::into)
}
Expand Down Expand Up @@ -815,6 +828,17 @@ impl SlidingSyncBuilder {
Arc::new(builder)
}

pub fn add_cached_list(
self: Arc<Self>,
list_builder: Arc<SlidingSyncListBuilder>,
) -> Result<Arc<Self>, ClientError> {
let mut builder = unwrap_or_clone_arc(self);
let list_builder = unwrap_or_clone_arc(list_builder);
builder.inner = RUNTIME
.block_on(async move { builder.inner.add_cached_list(list_builder.inner).await })?;
Ok(Arc::new(builder))
}

pub fn with_common_extensions(self: Arc<Self>) -> Arc<Self> {
let mut builder = unwrap_or_clone_arc(self);
builder.inner = builder.inner.with_common_extensions();
Expand Down
33 changes: 28 additions & 5 deletions crates/matrix-sdk/src/sliding_sync/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ pub struct SlidingSyncBuilder {
bump_event_types: Vec<TimelineEventType>,
extensions: Option<ExtensionsConfig>,
subscriptions: BTreeMap<OwnedRoomId, v4::RoomSubscription>,
rooms: BTreeMap<OwnedRoomId, SlidingSyncRoom>,
}

impl SlidingSyncBuilder {
Expand All @@ -47,6 +48,7 @@ impl SlidingSyncBuilder {
bump_event_types: Vec::new(),
extensions: None,
subscriptions: BTreeMap::new(),
rooms: BTreeMap::new(),
}
}

Expand All @@ -64,12 +66,35 @@ impl SlidingSyncBuilder {

/// Add the given list to the lists.
///
/// Replace any list with the name.
/// Replace any list with the same name.
pub fn add_list(mut self, list_builder: SlidingSyncListBuilder) -> Self {
self.lists.push(list_builder);
self
}

/// Enroll the list in caching, reloads it from the cache if possible, and
/// adds it to the list of lists.
///
/// This will raise an error if a [`storage_key()`][Self::storage_key] was
/// not set, or if there was a I/O error reading from the cache.
///
/// Replace any list with the same name.
pub async fn add_cached_list(mut self, mut list: SlidingSyncListBuilder) -> Result<Self> {
let Some(ref storage_key) = self.storage_key else {
return Err(super::error::Error::MissingStorageKeyForCaching.into());
};

let reloaded_rooms = list.set_cached_and_reload(&self.client, storage_key).await?;

for (key, frozen) in reloaded_rooms {
self.rooms
.entry(key)
.or_insert_with(|| SlidingSyncRoom::from_frozen(frozen, self.client.clone()));
}

Ok(self.add_list(list))
}

/// Activate e2ee, to-device-message and account data extensions if not yet
/// configured.
///
Expand Down Expand Up @@ -204,7 +229,6 @@ impl SlidingSyncBuilder {
let client = self.client;

let mut delta_token = None;
let mut rooms_found: BTreeMap<OwnedRoomId, SlidingSyncRoom> = BTreeMap::new();

let (internal_channel_sender, internal_channel_receiver) = channel(8);

Expand All @@ -221,15 +245,14 @@ impl SlidingSyncBuilder {
restore_sliding_sync_state(
&client,
storage_key,
&mut lists,
&lists,
&mut delta_token,
&mut rooms_found,
&mut self.extensions,
)
.await?;
}

let rooms = StdRwLock::new(rooms_found);
let rooms = StdRwLock::new(self.rooms);
let lists = StdRwLock::new(lists);

Ok(SlidingSync::new(SlidingSyncInner {
Expand Down
Loading

0 comments on commit 58dbe1e

Please sign in to comment.