Skip to content

Commit c812f0b

Browse files
committed
feat(sdk): don't trigger the ignored user list change if it hasn't changed since the previous time
1 parent 3caf76f commit c812f0b

File tree

4 files changed

+118
-11
lines changed

4 files changed

+118
-11
lines changed

crates/matrix-sdk-base/CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,10 @@ All notable changes to this project will be documented in this file.
88

99
### Features
1010

11+
- [**breaking**] The `Client::subscribe_to_ignore_user_list_changes()` method will now only trigger
12+
whenever the ignored user list has changed from what was previously known, instead of triggering
13+
every time an ignore-user-list event has been received from sync.
14+
([#4779](https://github.com/matrix-org/matrix-rust-sdk/pull/4779))
1115
- [**breaking**] The `MediaRetentionPolicy` can now trigger regular cleanups
1216
with its new `cleanup_frequency` setting.
1317
([#4603](https://github.com/matrix-org/matrix-rust-sdk/pull/4603))

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

Lines changed: 105 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1254,9 +1254,10 @@ impl BaseClient {
12541254

12551255
{
12561256
let _sync_lock = self.sync_lock().lock().await;
1257+
let prev_ignored_user_list = self.load_previous_ignored_user_list().await;
12571258
self.store.save_changes(&changes).await?;
12581259
*self.store.sync_token.write().await = Some(response.next_batch.clone());
1259-
self.apply_changes(&changes, room_info_notable_updates);
1260+
self.apply_changes(&changes, room_info_notable_updates, prev_ignored_user_list);
12601261
}
12611262

12621263
// Now that all the rooms information have been saved, update the display name
@@ -1286,10 +1287,17 @@ impl BaseClient {
12861287
Ok(response)
12871288
}
12881289

1290+
pub(crate) async fn load_previous_ignored_user_list(
1291+
&self,
1292+
) -> Option<Raw<IgnoredUserListEvent>> {
1293+
self.store().get_account_data_event_static().await.ok().flatten()
1294+
}
1295+
12891296
pub(crate) fn apply_changes(
12901297
&self,
12911298
changes: &StateChanges,
12921299
room_info_notable_updates: BTreeMap<OwnedRoomId, RoomInfoNotableUpdateReasons>,
1300+
prev_ignored_user_list: Option<Raw<IgnoredUserListEvent>>,
12931301
) {
12941302
if let Some(event) = changes.account_data.get(&GlobalAccountDataEventType::IgnoredUserList)
12951303
{
@@ -1298,8 +1306,27 @@ impl BaseClient {
12981306
let user_ids: Vec<String> =
12991307
event.content.ignored_users.keys().map(|id| id.to_string()).collect();
13001308

1301-
self.ignore_user_list_changes.set(user_ids);
1309+
// Try to only trigger the observable if the ignored user list has changed,
1310+
// from the previous time we've seen it. If we couldn't load the previous event
1311+
// for any reason, always trigger.
1312+
if let Some(prev_user_ids) =
1313+
prev_ignored_user_list.and_then(|raw| raw.deserialize().ok()).map(|event| {
1314+
event
1315+
.content
1316+
.ignored_users
1317+
.keys()
1318+
.map(|id| id.to_string())
1319+
.collect::<Vec<_>>()
1320+
})
1321+
{
1322+
if user_ids != prev_user_ids {
1323+
self.ignore_user_list_changes.set(user_ids);
1324+
}
1325+
} else {
1326+
self.ignore_user_list_changes.set(user_ids);
1327+
}
13021328
}
1329+
13031330
Err(error) => {
13041331
error!("Failed to deserialize ignored user list event: {error}")
13051332
}
@@ -1419,8 +1446,9 @@ impl BaseClient {
14191446
room_info.mark_members_synced();
14201447
changes.add_room(room_info);
14211448

1449+
let prev_ignored_user_list = self.load_previous_ignored_user_list().await;
14221450
self.store.save_changes(&changes).await?;
1423-
self.apply_changes(&changes, Default::default());
1451+
self.apply_changes(&changes, Default::default(), prev_ignored_user_list);
14241452

14251453
let _ = room.room_member_updates_sender.send(RoomMembersUpdate::FullReload);
14261454

@@ -1758,9 +1786,11 @@ fn handle_room_member_event_for_profiles(
17581786

17591787
#[cfg(test)]
17601788
mod tests {
1789+
use assert_matches2::assert_let;
1790+
use futures_util::FutureExt as _;
17611791
use matrix_sdk_test::{
17621792
async_test, event_factory::EventFactory, ruma_response_from_json, InvitedRoomBuilder,
1763-
LeftRoomBuilder, StateTestEvent, StrippedStateTestEvent, SyncResponseBuilder,
1793+
LeftRoomBuilder, StateTestEvent, StrippedStateTestEvent, SyncResponseBuilder, BOB,
17641794
};
17651795
use ruma::{
17661796
api::client as api, event_id, events::room::member::MembershipState, room_id, serde::Raw,
@@ -2152,4 +2182,75 @@ mod tests {
21522182
assert_eq!(member.display_name().unwrap(), "Invited Alice");
21532183
assert_eq!(member.avatar_url().unwrap().to_string(), "mxc://localhost/fewjilfewjil42");
21542184
}
2185+
2186+
#[async_test]
2187+
async fn test_ignored_user_list_changes() {
2188+
let user_id = user_id!("@alice:example.org");
2189+
let client = BaseClient::with_store_config(StoreConfig::new(
2190+
"cross-process-store-locks-holder-name".to_owned(),
2191+
));
2192+
client
2193+
.set_session_meta(
2194+
SessionMeta { user_id: user_id.to_owned(), device_id: "FOOBAR".into() },
2195+
#[cfg(feature = "e2e-encryption")]
2196+
None,
2197+
)
2198+
.await
2199+
.unwrap();
2200+
2201+
let mut subscriber = client.subscribe_to_ignore_user_list_changes();
2202+
assert!(subscriber.next().now_or_never().is_none());
2203+
2204+
let mut sync_builder = SyncResponseBuilder::new();
2205+
let response = sync_builder
2206+
.add_global_account_data_event(matrix_sdk_test::GlobalAccountDataTestEvent::Custom(
2207+
json!({
2208+
"content": {
2209+
"ignored_users": {
2210+
*BOB: {}
2211+
}
2212+
},
2213+
"type": "m.ignored_user_list",
2214+
}),
2215+
))
2216+
.build_sync_response();
2217+
client.receive_sync_response(response).await.unwrap();
2218+
2219+
assert_let!(Some(ignored) = subscriber.next().await);
2220+
assert_eq!(ignored, [BOB.to_string()]);
2221+
2222+
// Receive the same response.
2223+
let response = sync_builder
2224+
.add_global_account_data_event(matrix_sdk_test::GlobalAccountDataTestEvent::Custom(
2225+
json!({
2226+
"content": {
2227+
"ignored_users": {
2228+
*BOB: {}
2229+
}
2230+
},
2231+
"type": "m.ignored_user_list",
2232+
}),
2233+
))
2234+
.build_sync_response();
2235+
client.receive_sync_response(response).await.unwrap();
2236+
2237+
// No changes in the ignored list.
2238+
assert!(subscriber.next().now_or_never().is_none());
2239+
2240+
// Now remove Bob from the ignored list.
2241+
let response = sync_builder
2242+
.add_global_account_data_event(matrix_sdk_test::GlobalAccountDataTestEvent::Custom(
2243+
json!({
2244+
"content": {
2245+
"ignored_users": {}
2246+
},
2247+
"type": "m.ignored_user_list",
2248+
}),
2249+
))
2250+
.build_sync_response();
2251+
client.receive_sync_response(response).await.unwrap();
2252+
2253+
assert_let!(Some(ignored) = subscriber.next().await);
2254+
assert!(ignored.is_empty());
2255+
}
21552256
}

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

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2534,7 +2534,7 @@ mod tests {
25342534
client
25352535
.handle_room_account_data(room_id, &[tag_raw], &mut changes, &mut Default::default())
25362536
.await;
2537-
client.apply_changes(&changes, Default::default());
2537+
client.apply_changes(&changes, Default::default(), None);
25382538

25392539
// The `RoomInfo` is getting notified.
25402540
assert_ready!(room_info_subscriber);
@@ -2555,7 +2555,7 @@ mod tests {
25552555
client
25562556
.handle_room_account_data(room_id, &[tag_raw], &mut changes, &mut Default::default())
25572557
.await;
2558-
client.apply_changes(&changes, Default::default());
2558+
client.apply_changes(&changes, Default::default(), None);
25592559

25602560
// The `RoomInfo` is getting notified.
25612561
assert_ready!(room_info_subscriber);
@@ -2614,7 +2614,7 @@ mod tests {
26142614
client
26152615
.handle_room_account_data(room_id, &[tag_raw], &mut changes, &mut Default::default())
26162616
.await;
2617-
client.apply_changes(&changes, Default::default());
2617+
client.apply_changes(&changes, Default::default(), None);
26182618

26192619
// The `RoomInfo` is getting notified.
26202620
assert_ready!(room_info_subscriber);
@@ -2635,7 +2635,7 @@ mod tests {
26352635
client
26362636
.handle_room_account_data(room_id, &[tag_raw], &mut changes, &mut Default::default())
26372637
.await;
2638-
client.apply_changes(&changes, Default::default());
2638+
client.apply_changes(&changes, Default::default(), None);
26392639

26402640
// The `RoomInfo` is getting notified.
26412641
assert_ready!(room_info_subscriber);
@@ -3197,7 +3197,7 @@ mod tests {
31973197
assert!(room_info_notable_update.try_recv().is_err());
31983198

31993199
// Then updating the room info will store the event,
3200-
client.apply_changes(&changes, room_info_notable_updates);
3200+
client.apply_changes(&changes, room_info_notable_updates, None);
32013201
assert_eq!(room.latest_event().unwrap().event_id(), event.event_id());
32023202

32033203
// And wake up the subscriber.

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

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -109,8 +109,9 @@ impl BaseClient {
109109
.await?;
110110

111111
trace!("ready to submit e2ee changes to store");
112+
let prev_ignored_user_list = self.load_previous_ignored_user_list().await;
112113
self.store.save_changes(&changes).await?;
113-
self.apply_changes(&changes, room_info_notable_updates);
114+
self.apply_changes(&changes, room_info_notable_updates, prev_ignored_user_list);
114115
trace!("applied e2ee changes");
115116

116117
Ok(Some(to_device))
@@ -324,8 +325,9 @@ impl BaseClient {
324325
changes.ambiguity_maps = ambiguity_cache.cache;
325326

326327
trace!("ready to submit changes to store");
328+
let prev_ignored_user_list = self.load_previous_ignored_user_list().await;
327329
store.save_changes(&changes).await?;
328-
self.apply_changes(&changes, room_info_notable_updates);
330+
self.apply_changes(&changes, room_info_notable_updates, prev_ignored_user_list);
329331
trace!("applied changes");
330332

331333
// Now that all the rooms information have been saved, update the display name

0 commit comments

Comments
 (0)