Skip to content

Commit 8538bdc

Browse files
authored
fix[state store]: Persist stripped rooms in the right bucket
fixes #467 as well as persistence problems with the indexeddb store
2 parents 59d21d9 + 7aa9944 commit 8538bdc

File tree

8 files changed

+127
-71
lines changed

8 files changed

+127
-71
lines changed

crates/matrix-sdk-base/src/client.rs

Lines changed: 20 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -565,26 +565,24 @@ impl BaseClient {
565565
(BTreeMap::new(), BTreeMap::new()),
566566
|(mut members, mut state_events), raw_event| {
567567
match raw_event.deserialize() {
568-
Ok(e) => {
569-
570-
if let AnyStrippedStateEvent::RoomMember(member) = e {
571-
match StrippedMemberEvent::try_from(member) {
572-
Ok(m) => {
573-
members.insert(m.state_key.clone(), m);
574-
}
575-
Err(e) => warn!(
576-
"Stripped member event in room {} has an invalid state key {:?}",
577-
room_info.room_id, e
578-
),
568+
Ok(AnyStrippedStateEvent::RoomMember(member)) => {
569+
match StrippedMemberEvent::try_from(member) {
570+
Ok(m) => {
571+
members.insert(m.state_key.clone(), m);
579572
}
580-
} else {
581-
room_info.handle_state_event(&e.content());
582-
state_events
583-
.entry(e.content().event_type().to_owned())
584-
.or_insert_with(BTreeMap::new)
585-
.insert(e.state_key().to_owned(), raw_event.clone());
573+
Err(e) => warn!(
574+
"Stripped member event in room {} has an invalid state key {:?}",
575+
room_info.room_id, e
576+
),
586577
}
587578
}
579+
Ok(e) => {
580+
room_info.handle_state_event(&e.content());
581+
state_events
582+
.entry(e.content().event_type().to_owned())
583+
.or_insert_with(BTreeMap::new)
584+
.insert(e.state_key().to_owned(), raw_event.clone());
585+
}
588586
Err(err) => {
589587
warn!(
590588
"Couldn't deserialize stripped state event for room {}: {:?}",
@@ -900,13 +898,6 @@ impl BaseClient {
900898
}
901899

902900
for (room_id, new_info) in rooms.invite {
903-
{
904-
let room = self.store.get_or_create_room(&room_id, RoomType::Invited).await;
905-
let mut room_info = room.clone_info();
906-
room_info.mark_as_invited();
907-
changes.add_room(room_info);
908-
}
909-
910901
let room = self.store.get_or_create_stripped_room(&room_id).await;
911902
let mut room_info = room.clone_info();
912903

@@ -967,6 +958,11 @@ impl BaseClient {
967958
room.update_summary(room_info.clone())
968959
}
969960
}
961+
for (room_id, room_info) in &changes.stripped_room_infos {
962+
if let Some(room) = self.store.get_stripped_room(room_id) {
963+
room.update_summary(room_info.clone())
964+
}
965+
}
970966
}
971967

972968
/// Receive a get member events response and convert it to a deserialized

crates/matrix-sdk-base/src/rooms/normal.rs

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -503,10 +503,6 @@ impl RoomInfo {
503503
self.room_type = RoomType::Left;
504504
}
505505

506-
pub(crate) fn mark_as_invited(&mut self) {
507-
self.room_type = RoomType::Invited;
508-
}
509-
510506
pub(crate) fn mark_members_synced(&mut self) {
511507
self.members_synced = true;
512508
}

crates/matrix-sdk-base/src/store/indexeddb_store.rs

Lines changed: 21 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ mod KEYS {
7070
pub const PRESENCE: &'static str = "presence";
7171
pub const ROOM_ACCOUNT_DATA: &'static str = "room_account_data";
7272

73-
pub const STRIPPED_ROOM_INFO: &'static str = "stripped_room_info";
73+
pub const STRIPPED_ROOM_INFOS: &'static str = "stripped_room_infos";
7474
pub const STRIPPED_MEMBERS: &'static str = "stripped_members";
7575
pub const STRIPPED_ROOM_STATE: &'static str = "stripped_room_state";
7676

@@ -137,7 +137,7 @@ impl IndexeddbStore {
137137
db.create_object_store(KEYS::PRESENCE)?;
138138
db.create_object_store(KEYS::ROOM_ACCOUNT_DATA)?;
139139

140-
db.create_object_store(KEYS::STRIPPED_ROOM_INFO)?;
140+
db.create_object_store(KEYS::STRIPPED_ROOM_INFOS)?;
141141
db.create_object_store(KEYS::STRIPPED_MEMBERS)?;
142142
db.create_object_store(KEYS::STRIPPED_ROOM_STATE)?;
143143

@@ -261,8 +261,8 @@ impl IndexeddbStore {
261261
pub async fn get_sync_token(&self) -> Result<Option<String>> {
262262
Ok(self
263263
.inner
264-
.transaction_on_one_with_mode(KEYS::SESSION, IdbTransactionMode::Readonly)?
265-
.object_store(KEYS::SESSION)?
264+
.transaction_on_one_with_mode(KEYS::SYNC_TOKEN, IdbTransactionMode::Readonly)?
265+
.object_store(KEYS::SYNC_TOKEN)?
266266
.get(&JsValue::from_str(KEYS::SYNC_TOKEN))?
267267
.await?
268268
.map(|f| self.deserialize_event(f))
@@ -283,7 +283,7 @@ impl IndexeddbStore {
283283
(!changes.receipts.is_empty(), KEYS::ROOM_EVENT_RECEIPTS),
284284
(!changes.stripped_state.is_empty(), KEYS::STRIPPED_ROOM_STATE),
285285
(!changes.stripped_members.is_empty(), KEYS::STRIPPED_MEMBERS),
286-
(!changes.invited_room_info.is_empty(), KEYS::STRIPPED_ROOM_INFO),
286+
(!changes.stripped_room_infos.is_empty(), KEYS::STRIPPED_ROOM_INFOS),
287287
]
288288
.iter()
289289
.filter_map(|(id, key)| if *id { Some(*key) } else { None })
@@ -369,9 +369,9 @@ impl IndexeddbStore {
369369
}
370370
}
371371

372-
if !changes.invited_room_info.is_empty() {
373-
let store = tx.object_store(KEYS::STRIPPED_ROOM_INFO)?;
374-
for (room_id, info) in &changes.invited_room_info {
372+
if !changes.stripped_room_infos.is_empty() {
373+
let store = tx.object_store(KEYS::STRIPPED_ROOM_INFOS)?;
374+
for (room_id, info) in &changes.stripped_room_infos {
375375
store.put_key_val(&room_id.encode(), &self.serialize_event(&info)?)?;
376376
}
377377
}
@@ -607,8 +607,8 @@ impl IndexeddbStore {
607607
pub async fn get_stripped_room_infos(&self) -> Result<Vec<RoomInfo>> {
608608
let entries = self
609609
.inner
610-
.transaction_on_one_with_mode(KEYS::STRIPPED_ROOM_INFO, IdbTransactionMode::Readonly)?
611-
.object_store(KEYS::STRIPPED_ROOM_INFO)?
610+
.transaction_on_one_with_mode(KEYS::STRIPPED_ROOM_INFOS, IdbTransactionMode::Readonly)?
611+
.object_store(KEYS::STRIPPED_ROOM_INFOS)?
612612
.get_all()?
613613
.await?
614614
.iter()
@@ -623,16 +623,16 @@ impl IndexeddbStore {
623623
room_id: &RoomId,
624624
display_name: &str,
625625
) -> Result<BTreeSet<Box<UserId>>> {
626-
let range = (room_id, display_name).encode_to_range().map_err(|e| StoreError::Codec(e))?;
627-
Ok(self
628-
.inner
629-
.transaction_on_one_with_mode(KEYS::JOINED_USER_IDS, IdbTransactionMode::Readonly)?
630-
.object_store(KEYS::JOINED_USER_IDS)?
631-
.get_all_with_key(&range)?
626+
self.inner
627+
.transaction_on_one_with_mode(KEYS::DISPLAY_NAMES, IdbTransactionMode::Readonly)?
628+
.object_store(KEYS::DISPLAY_NAMES)?
629+
.get(&(room_id, display_name).encode())?
632630
.await?
633-
.iter()
634-
.filter_map(|f| self.deserialize_event::<Box<UserId>>(f).ok())
635-
.collect::<BTreeSet<_>>())
631+
.map(|f| {
632+
self.deserialize_event::<BTreeSet<Box<UserId>>>(f)
633+
.map_err::<StoreError, _>(|e| e.into())
634+
})
635+
.unwrap_or_else(|| Ok(Default::default()))
636636
}
637637

638638
pub async fn get_account_data_event(
@@ -658,7 +658,7 @@ impl IndexeddbStore {
658658
.inner
659659
.transaction_on_one_with_mode(KEYS::ROOM_ACCOUNT_DATA, IdbTransactionMode::Readonly)?
660660
.object_store(KEYS::ROOM_ACCOUNT_DATA)?
661-
.get(&JsValue::from_str(&format!("{}:{}", room_id.as_str(), event_type)))?
661+
.get(&(room_id.as_str(), event_type.as_str()).encode())?
662662
.await?
663663
.map(|f| self.deserialize_event(f).map_err::<StoreError, _>(|e| e.into()))
664664
.transpose()?)
@@ -794,7 +794,7 @@ impl IndexeddbStore {
794794
}
795795

796796
async fn remove_room(&self, room_id: &RoomId) -> Result<()> {
797-
let direct_stores = [KEYS::ROOM_INFOS, KEYS::STRIPPED_ROOM_INFO];
797+
let direct_stores = [KEYS::ROOM_INFOS, KEYS::STRIPPED_ROOM_INFOS];
798798

799799
let prefixed_stores = [
800800
KEYS::MEMBERS,

crates/matrix-sdk-base/src/store/integration_tests.rs

Lines changed: 55 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -184,7 +184,7 @@ macro_rules! statestore_integration_tests {
184184
)]),
185185
)]),
186186
);
187-
changes.invited_room_info.insert(stripped_room_id.to_owned(), stripped_room.clone());
187+
188188
changes.add_stripped_room(stripped_room);
189189

190190
let stripped_member_json: &JsonValue = &test_json::MEMBER_STRIPPED;
@@ -229,6 +229,46 @@ macro_rules! statestore_integration_tests {
229229

230230
}
231231

232+
#[async_test]
233+
async fn test_populate_store() -> Result<()> {
234+
let room_id = room_id();
235+
let user_id = user_id();
236+
let inner_store = get_store().await?;
237+
238+
let store = populated_store(Box::new(inner_store)).await?;
239+
240+
assert!(store.get_sync_token().await?.is_some());
241+
assert!(store.get_presence_event(user_id).await?.is_some());
242+
assert_eq!(store.get_room_infos().await?.len(), 1);
243+
assert_eq!(store.get_stripped_room_infos().await?.len(), 1);
244+
assert!(store.get_account_data_event(EventType::PushRules).await?.is_some());
245+
246+
assert!(store.get_state_event(room_id, EventType::RoomName, "").await?.is_some());
247+
assert_eq!(store.get_state_events(room_id, EventType::RoomTopic).await?.len(), 1);
248+
assert!(store.get_profile(room_id, user_id).await?.is_some());
249+
assert!(store.get_member_event(room_id, user_id).await?.is_some());
250+
assert_eq!(store.get_user_ids(room_id).await?.len(), 2);
251+
assert_eq!(store.get_invited_user_ids(room_id).await?.len(), 1);
252+
assert_eq!(store.get_joined_user_ids(room_id).await?.len(), 1);
253+
assert_eq!(store.get_users_with_display_name(room_id, "example").await?.len(), 2);
254+
assert!(store
255+
.get_room_account_data_event(room_id, EventType::Tag)
256+
.await?
257+
.is_some());
258+
assert!(store
259+
.get_user_room_receipt_event(room_id, ReceiptType::Read, user_id)
260+
.await?
261+
.is_some());
262+
assert_eq!(
263+
store
264+
.get_event_room_receipt_events(room_id, ReceiptType::Read, first_receipt_event_id())
265+
.await?
266+
.len(),
267+
1
268+
);
269+
Ok(())
270+
}
271+
232272
#[async_test]
233273
async fn test_member_saving() {
234274
let store = get_store().await.unwrap();
@@ -422,6 +462,19 @@ macro_rules! statestore_integration_tests {
422462
Ok(())
423463
}
424464

465+
#[async_test]
466+
async fn test_persist_invited_room() -> Result<()> {
467+
let stripped_room_id = stripped_room_id();
468+
let inner_store = get_store().await?;
469+
let store = populated_store(Box::new(inner_store)).await?;
470+
471+
assert_eq!(store.get_stripped_room_infos().await?.len(), 1);
472+
assert!(store.get_stripped_room(stripped_room_id).is_some());
473+
474+
// populate rooom
475+
Ok(())
476+
}
477+
425478
#[async_test]
426479
async fn test_room_removal() -> Result<()> {
427480
let room_id = room_id();
@@ -431,11 +484,9 @@ macro_rules! statestore_integration_tests {
431484

432485
let store = populated_store(Box::new(inner_store)).await?;
433486

434-
// We assume the store was correctly populated like the test above.
435-
436487
store.remove_room(room_id).await?;
437488

438-
assert_eq!(store.get_room_infos().await?.len(), 1);
489+
assert_eq!(store.get_room_infos().await?.len(), 0);
439490
assert_eq!(store.get_stripped_room_infos().await?.len(), 1);
440491

441492
assert!(store.get_state_event(room_id, EventType::RoomName, "").await?.is_none());

crates/matrix-sdk-base/src/store/memory_store.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ pub struct MemoryStore {
5656
room_info: Arc<DashMap<Box<RoomId>, RoomInfo>>,
5757
room_state: Arc<DashMap<Box<RoomId>, DashMap<String, DashMap<String, Raw<AnySyncStateEvent>>>>>,
5858
room_account_data: Arc<DashMap<Box<RoomId>, DashMap<String, Raw<AnyRoomAccountDataEvent>>>>,
59-
stripped_room_info: Arc<DashMap<Box<RoomId>, RoomInfo>>,
59+
stripped_room_infos: Arc<DashMap<Box<RoomId>, RoomInfo>>,
6060
stripped_room_state:
6161
Arc<DashMap<Box<RoomId>, DashMap<String, DashMap<String, Raw<AnyStrippedStateEvent>>>>>,
6262
stripped_members: Arc<DashMap<Box<RoomId>, DashMap<Box<UserId>, StrippedMemberEvent>>>,
@@ -85,7 +85,7 @@ impl MemoryStore {
8585
room_info: Default::default(),
8686
room_state: Default::default(),
8787
room_account_data: Default::default(),
88-
stripped_room_info: Default::default(),
88+
stripped_room_infos: Default::default(),
8989
stripped_room_state: Default::default(),
9090
stripped_members: Default::default(),
9191
presence: Default::default(),
@@ -211,8 +211,8 @@ impl MemoryStore {
211211
self.presence.insert(sender.clone(), event.clone());
212212
}
213213

214-
for (room_id, info) in &changes.invited_room_info {
215-
self.stripped_room_info.insert(room_id.clone(), info.clone());
214+
for (room_id, info) in &changes.stripped_room_infos {
215+
self.stripped_room_infos.insert(room_id.clone(), info.clone());
216216
}
217217

218218
for (room, events) in &changes.stripped_members {
@@ -350,7 +350,7 @@ impl MemoryStore {
350350
}
351351

352352
fn get_stripped_room_infos(&self) -> Vec<RoomInfo> {
353-
self.stripped_room_info.iter().map(|r| r.clone()).collect()
353+
self.stripped_room_infos.iter().map(|r| r.clone()).collect()
354354
}
355355

356356
async fn get_account_data_event(
@@ -450,7 +450,7 @@ impl MemoryStore {
450450
self.room_info.remove(room_id);
451451
self.room_state.remove(room_id);
452452
self.room_account_data.remove(room_id);
453-
self.stripped_room_info.remove(room_id);
453+
self.stripped_room_infos.remove(room_id);
454454
self.stripped_room_state.remove(room_id);
455455
self.stripped_members.remove(room_id);
456456
self.room_user_receipts.remove(room_id);

crates/matrix-sdk-base/src/store/mod.rs

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -473,7 +473,13 @@ impl Store {
473473
.or_else(|| self.get_stripped_room(room_id))
474474
}
475475

476-
fn get_stripped_room(&self, room_id: &RoomId) -> Option<Room> {
476+
/// Get all the rooms this store knows about.
477+
pub fn get_stripped_rooms(&self) -> Vec<Room> {
478+
self.stripped_rooms.iter().filter_map(|r| self.get_stripped_room(r.key())).collect()
479+
}
480+
481+
/// Get the stripped room with the given room id.
482+
pub fn get_stripped_room(&self, room_id: &RoomId) -> Option<Room> {
477483
self.stripped_rooms.get(room_id).map(|r| r.clone())
478484
}
479485

@@ -488,6 +494,10 @@ impl Store {
488494
}
489495

490496
pub(crate) async fn get_or_create_room(&self, room_id: &RoomId, room_type: RoomType) -> Room {
497+
if room_type == RoomType::Invited {
498+
return self.get_or_create_stripped_room(room_id).await;
499+
}
500+
491501
let session = self.session.read().await;
492502
let user_id = &session.as_ref().expect("Creating room while not being logged in").user_id;
493503

@@ -543,8 +553,9 @@ pub struct StateChanges {
543553
BTreeMap<Box<RoomId>, BTreeMap<String, BTreeMap<String, Raw<AnyStrippedStateEvent>>>>,
544554
/// A mapping of `RoomId` to a map of users and their `StrippedMemberEvent`.
545555
pub stripped_members: BTreeMap<Box<RoomId>, BTreeMap<Box<UserId>, StrippedMemberEvent>>,
546-
/// A map of `RoomId` to `RoomInfo`.
547-
pub invited_room_info: BTreeMap<Box<RoomId>, RoomInfo>,
556+
/// A map of `RoomId` to `RoomInfo` for stripped rooms (e.g. for invites or
557+
/// while knocking)
558+
pub stripped_room_infos: BTreeMap<Box<RoomId>, RoomInfo>,
548559

549560
/// A map from room id to a map of a display name and a set of user ids that
550561
/// share that display name in the given room.
@@ -571,7 +582,7 @@ impl StateChanges {
571582

572583
/// Update the `StateChanges` struct with the given `RoomInfo`.
573584
pub fn add_stripped_room(&mut self, room: RoomInfo) {
574-
self.room_infos.insert(room.room_id.as_ref().to_owned(), room);
585+
self.stripped_room_infos.insert(room.room_id.as_ref().to_owned(), room);
575586
}
576587

577588
/// Update the `StateChanges` struct with the given `AnyBasicEvent`.

0 commit comments

Comments
 (0)