Skip to content

Commit cd8dc22

Browse files
committed
chore(sdk): Remove RoomListEntry and ops in Sliding Sync.
This patch removes everything related to the computation of `ops` from a sliding sync response. With the recent `RoomList`'s client-side sorting project, we no longer need to handle these `ops`. Moreover, the simplified sliding sync specification that is coming removes the `ops`. A `SlidingSyncList` was containing a `rooms` field. It's removed by this patch. Consequently, all the `SlidingSyncList::room_list` and `::room_list_stream` methods are also removed. A `FrozenSlidingSyncList` was containing the `FrozenSlidingSyncRoom`. This patch moves the `FrozenSlidingSyncRoom`s inside `FrozenSlidingSync`. Why is it still correct? We only want to keep the `SlidingSyncRoom::timeline_queue` in the cache for the moment (until the `EventCache` has a persistent storage). Since a `SlidingSyncList` no longer holds any information about the rooms, and since `SlidingSync` itself has all the `SlidingSyncRoom`, this move is natural and still valid. Bye bye all this code :'-).
1 parent 02dddb4 commit cd8dc22

File tree

10 files changed

+167
-1506
lines changed

10 files changed

+167
-1506
lines changed

crates/matrix-sdk/src/lib.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ pub use room::Room;
8686
pub use ruma::{IdParseError, OwnedServerName, ServerName};
8787
#[cfg(feature = "experimental-sliding-sync")]
8888
pub use sliding_sync::{
89-
RoomListEntry, SlidingSync, SlidingSyncBuilder, SlidingSyncList, SlidingSyncListBuilder,
89+
SlidingSync, SlidingSyncBuilder, SlidingSyncList, SlidingSyncListBuilder,
9090
SlidingSyncListLoadingState, SlidingSyncMode, SlidingSyncRoom, UpdateSummary,
9191
};
9292

crates/matrix-sdk/src/sliding_sync/README.md

+12-63
Original file line numberDiff line numberDiff line change
@@ -95,15 +95,11 @@ list-object. Once a list has been added to [`SlidingSync`], a cloned shared
9595
copy can be retrieved by calling `SlidingSync::list()`, providing the name
9696
of the list. Next to the configuration settings (like name and
9797
`timeline_limit`), the list provides the stateful
98-
[`maximum_number_of_rooms`](SlidingSyncList::maximum_number_of_rooms),
99-
[`room_list`](SlidingSyncList::room_list) and
98+
[`maximum_number_of_rooms`](SlidingSyncList::maximum_number_of_rooms) and
10099
[`state`](SlidingSyncList::state):
101100

102101
- `maximum_number_of_rooms` is the number of rooms _total_ there were found
103102
matching the filters given.
104-
- `room_list` is a vector of `maximum_number_of_rooms` [`RoomListEntry`]'s
105-
at the current state. `RoomListEntry`'s only hold `the room_id` if given,
106-
the [Rooms API](#rooms) holds the actual information about each room
107103
- `state` is a [`SlidingSyncMode`] signalling meta information about the
108104
list and its stateful data — whether this is the state loaded from local
109105
cache, whether the [full sync](#helper-lists) is in progress or whether
@@ -149,32 +145,6 @@ visible in any list. The most common case for using this API is when the user
149145
enters a room - as we want to receive the incoming new messages regardless of
150146
whether the room is pushed out of the lists room list.
151147

152-
### Room List Entries
153-
154-
As the room list of each list is a vec of the `maximum_number_of_rooms` len
155-
but a room may only know of a subset of entries for sure at any given time,
156-
these entries are wrapped in [`RoomListEntry`][]. This type, in close
157-
proximity to the [specification][MSC], can be either `Empty`, `Filled` or
158-
`Invalidated`, signaling the state of each entry position.
159-
- `Empty` we don't know what sits here at this position in the list.
160-
- `Filled`: there is this `room_id` at this position.
161-
- `Invalidated` in that sense means that we _knew_ what was here before, but
162-
can't be sure anymore this is still accurate. This occurs when we move the
163-
sliding window (by changing the ranges) or when a room might drop out of
164-
the window we are looking at. For the sake of displaying, this is probably
165-
still fine to display to be at this position, but we can't be sure
166-
anymore.
167-
168-
Because `Invalidated` occurs whenever a room we knew about before drops out
169-
of focus, we aren't updated about its changes anymore either, there could be
170-
duplicates rooms within invalidated rooms as well as in the union of
171-
invalidated and filled rooms. Keep that in mind, as most UI frameworks don't
172-
like it when their list entries aren't unique.
173-
174-
When [restoring from cold cache][#caching] the room list also only
175-
propagated with `Invalidated` rooms. So if you want to be able to display
176-
data quickly, ensure you are able to render `Invalidated` entries.
177-
178148
### Unsubscribe
179149

180150
Don't forget to [unsubscribe](`SlidingSync::unsubscribe_from_room`) when the
@@ -345,14 +315,12 @@ subscribing to updates via [`eyeball`].
345315

346316
## Caching
347317

348-
All room data, for filled but also _invalidated_ rooms, including the entire
349-
timeline events as well as all list `room_lists` and
350-
`maximum_number_of_rooms` are held in memory (unless one `pop`s the list
351-
out).
318+
All room data, including the entire timeline events as well as all lists and
319+
`maximum_number_of_rooms` are held in memory (unless one `pop`s the list out).
352320

353-
Sliding Sync instances are also cached on disk, and restored from disk at creation. This ensures
354-
that we keep track of important position markers, like the `since` tokens used in the sync
355-
requests.
321+
Sliding Sync instances are also cached on disk, and restored from disk at
322+
creation. This ensures that we keep track of important position markers, like
323+
the `since` tokens used in the sync requests.
356324

357325
Caching for lists can be enabled independently, using the
358326
[`add_cached_list`][`SlidingSyncBuilder::add_cached_list`] method, assuming
@@ -370,10 +338,6 @@ are stored to storage, but only retrieved upon `build()` of the
370338
the data from storage (to avoid inconsistencies) and might require more data to
371339
be sent in their first request than if they were loaded from a cold cache.
372340

373-
When loading from storage `room_list` entries found are set to
374-
`Invalidated` — the initial setting here is communicated as a single
375-
`VecDiff::Replace` event through the [reactive API](#reactive-api).
376-
377341
Only the latest 10 timeline items of each room are cached and they are reset
378342
whenever a new set of timeline items is received by the server.
379343

@@ -446,30 +410,15 @@ let sliding_sync = sliding_sync_builder
446410
.build()
447411
.await?;
448412
449-
// subscribe to the list APIs for updates
450-
451-
let ((_, list_state_stream), list_count_stream, (_, list_stream)) = sliding_sync.on_list(&active_list_name, |list| {
452-
ready((list.state_stream(), list.maximum_number_of_rooms_stream(), list.room_list_stream()))
453-
}).await.unwrap();
454-
455-
tokio::spawn(async move {
456-
pin_mut!(list_state_stream);
457-
while let Some(new_state) = list_state_stream.next().await {
458-
info!("active-list switched state to {new_state:?}");
459-
}
460-
});
461413
462414
tokio::spawn(async move {
463-
pin_mut!(list_count_stream);
464-
while let Some(new_count) = list_count_stream.next().await {
465-
info!("active-list new count: {new_count:?}");
466-
}
467-
});
415+
// subscribe to rooms updates
416+
let (_rooms, rooms_stream) = client.rooms_stream();
417+
// do something with `_rooms`
468418
469-
tokio::spawn(async move {
470-
pin_mut!(list_stream);
471-
while let Some(v_diff) = list_stream.next().await {
472-
info!("active-list room list diff update: {v_diff:?}");
419+
pin_mut!(rooms_stream);
420+
while let Some(_room) = rooms_stream.next().await {
421+
info!("a room has been updated");
473422
}
474423
});
475424

crates/matrix-sdk/src/sliding_sync/builder.rs

+2-8
Original file line numberDiff line numberDiff line change
@@ -95,16 +95,10 @@ impl SlidingSyncBuilder {
9595
/// cache.
9696
///
9797
/// Replace any list with the same name.
98-
pub async fn add_cached_list(mut self, mut list: SlidingSyncListBuilder) -> Result<Self> {
98+
pub async fn add_cached_list(self, mut list: SlidingSyncListBuilder) -> Result<Self> {
9999
let _timer = timer!(format!("restoring (loading+processing) list {}", list.name));
100100

101-
let reloaded_rooms = list.set_cached_and_reload(&self.client, &self.storage_key).await?;
102-
103-
for (key, frozen) in reloaded_rooms {
104-
self.rooms
105-
.entry(key)
106-
.or_insert_with(|| SlidingSyncRoom::from_frozen(frozen, self.client.clone()));
107-
}
101+
list.set_cached_and_reload(&self.client, &self.storage_key).await?;
108102

109103
Ok(self.add_list(list))
110104
}

crates/matrix-sdk/src/sliding_sync/cache.rs

+40-15
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,12 @@ use std::collections::BTreeMap;
88

99
use matrix_sdk_base::{StateStore, StoreError};
1010
use matrix_sdk_common::timer;
11-
use ruma::UserId;
11+
use ruma::{OwnedRoomId, UserId};
1212
use tracing::{trace, warn};
1313

1414
use super::{
1515
FrozenSlidingSync, FrozenSlidingSyncList, SlidingSync, SlidingSyncList,
16-
SlidingSyncPositionMarkers,
16+
SlidingSyncPositionMarkers, SlidingSyncRoom,
1717
};
1818
#[cfg(feature = "e2e-encryption")]
1919
use crate::sliding_sync::FrozenSlidingSyncPos;
@@ -88,7 +88,10 @@ pub(super) async fn store_sliding_sync_state(
8888
storage
8989
.set_custom_value(
9090
instance_storage_key.as_bytes(),
91-
serde_json::to_vec(&FrozenSlidingSync::new(position))?,
91+
serde_json::to_vec(&FrozenSlidingSync::new(
92+
position,
93+
&*sliding_sync.inner.rooms.read().await,
94+
))?,
9295
)
9396
.await?;
9497

@@ -106,8 +109,6 @@ pub(super) async fn store_sliding_sync_state(
106109

107110
// Write every `SlidingSyncList` that's configured for caching into the store.
108111
let frozen_lists = {
109-
let rooms_lock = sliding_sync.inner.rooms.read().await;
110-
111112
sliding_sync
112113
.inner
113114
.lists
@@ -118,7 +119,7 @@ pub(super) async fn store_sliding_sync_state(
118119
.map(|(list_name, list)| {
119120
Ok((
120121
format_storage_key_for_sliding_sync_list(storage_key, list_name),
121-
serde_json::to_vec(&FrozenSlidingSyncList::freeze(list, &rooms_lock))?,
122+
serde_json::to_vec(&FrozenSlidingSyncList::freeze(list))?,
122123
))
123124
})
124125
.collect::<Result<Vec<_>, crate::Error>>()?
@@ -163,9 +164,9 @@ pub(super) async fn restore_sliding_sync_list(
163164
// error, we remove the entry from the cache and keep the list in its initial
164165
// state.
165166
warn!(
166-
list_name,
167-
"failed to deserialize the list from the cache, it is obsolete; removing the cache entry!"
168-
);
167+
list_name,
168+
"failed to deserialize the list from the cache, it is obsolete; removing the cache entry!"
169+
);
169170
// Let's clear the list and stop here.
170171
invalidate_cached_list(storage, storage_key, list_name).await;
171172
}
@@ -186,6 +187,7 @@ pub(super) struct RestoredFields {
186187
pub delta_token: Option<String>,
187188
pub to_device_token: Option<String>,
188189
pub pos: Option<String>,
190+
pub rooms: BTreeMap<OwnedRoomId, SlidingSyncRoom>,
189191
}
190192

191193
/// Restore the `SlidingSync`'s state from what is stored in the storage.
@@ -221,7 +223,11 @@ pub(super) async fn restore_sliding_sync_state(
221223
.map(|custom_value| serde_json::from_slice::<FrozenSlidingSync>(&custom_value))
222224
{
223225
// `SlidingSync` has been found and successfully deserialized.
224-
Some(Ok(FrozenSlidingSync { to_device_since, delta_token: frozen_delta_token })) => {
226+
Some(Ok(FrozenSlidingSync {
227+
to_device_since,
228+
delta_token: frozen_delta_token,
229+
rooms: frozen_rooms,
230+
})) => {
225231
trace!("Successfully read the `SlidingSync` from the cache");
226232
// Only update the to-device token if we failed to read it from the crypto store
227233
// above.
@@ -246,6 +252,16 @@ pub(super) async fn restore_sliding_sync_state(
246252
}
247253
}
248254
}
255+
256+
restored_fields.rooms = frozen_rooms
257+
.into_iter()
258+
.map(|frozen_room| {
259+
(
260+
frozen_room.room_id.clone(),
261+
SlidingSyncRoom::from_frozen(frozen_room, client.clone()),
262+
)
263+
})
264+
.collect();
249265
}
250266

251267
// `SlidingSync` has been found, but it wasn't possible to deserialize it. It's
@@ -281,11 +297,11 @@ mod tests {
281297
use matrix_sdk_test::async_test;
282298

283299
use super::{
284-
clean_storage, format_storage_key_for_sliding_sync,
300+
super::FrozenSlidingSyncRoom, clean_storage, format_storage_key_for_sliding_sync,
285301
format_storage_key_for_sliding_sync_list, format_storage_key_prefix,
286-
restore_sliding_sync_state, store_sliding_sync_state,
302+
restore_sliding_sync_state, store_sliding_sync_state, SlidingSyncList,
287303
};
288-
use crate::{test_utils::logged_in_client, Result, SlidingSyncList};
304+
use crate::{test_utils::logged_in_client, Result};
289305

290306
#[allow(clippy::await_holding_lock)]
291307
#[async_test]
@@ -440,6 +456,9 @@ mod tests {
440456
#[cfg(feature = "e2e-encryption")]
441457
#[async_test]
442458
async fn test_sliding_sync_high_level_cache_and_restore() -> Result<()> {
459+
use imbl::Vector;
460+
use ruma::owned_room_id;
461+
443462
use crate::sliding_sync::FrozenSlidingSync;
444463

445464
let client = logged_in_client(Some("https://foo.bar".to_owned())).await;
@@ -513,6 +532,11 @@ mod tests {
513532
serde_json::to_vec(&FrozenSlidingSync {
514533
to_device_since: Some(to_device_token.clone()),
515534
delta_token: Some(delta_token.clone()),
535+
rooms: vec![FrozenSlidingSyncRoom {
536+
room_id: owned_room_id!("!r0:matrix.org"),
537+
prev_batch: Some("t0ken".to_owned()),
538+
timeline_queue: Vector::new(),
539+
}],
516540
})?,
517541
)
518542
.await?;
@@ -521,11 +545,12 @@ mod tests {
521545
.await?
522546
.expect("must have restored fields");
523547

524-
// After restoring, the delta token, the to-device since token, and stream
525-
// position could be read from the state store.
548+
// After restoring, the delta token, the to-device since token, stream
549+
// position and rooms could be read from the state store.
526550
assert_eq!(restored_fields.delta_token.unwrap(), delta_token);
527551
assert_eq!(restored_fields.to_device_token.unwrap(), to_device_token);
528552
assert_eq!(restored_fields.pos.unwrap(), pos);
553+
assert_eq!(restored_fields.rooms.len(), 1);
529554

530555
Ok(())
531556
}

0 commit comments

Comments
 (0)