Skip to content

Commit

Permalink
feat(knocking): add code to process knocked rooms separately during sync
Browse files Browse the repository at this point in the history
  • Loading branch information
jmartinesp committed Oct 16, 2024
1 parent 30f3a3c commit 664f6d5
Show file tree
Hide file tree
Showing 7 changed files with 348 additions and 60 deletions.
83 changes: 65 additions & 18 deletions crates/matrix-sdk-base/src/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -523,34 +523,35 @@ impl BaseClient {
Ok(timeline)
}

/// Handles the stripped state events in `invite_state`, modifying the
/// room's info and posting notifications as needed.
///
/// * `room` - The [`Room`] to modify.
/// * `events` - The contents of `invite_state` in the form of list of pairs
/// of raw stripped state events with their deserialized counterpart.
/// * `push_rules` - The push rules for this room.
/// * `room_info` - The current room's info.
/// * `changes` - The accumulated list of changes to apply once the
/// processing is finished.
/// * `notifications` - Notifications to post for the current room.
#[instrument(skip_all, fields(room_id = ?room_info.room_id))]
pub(crate) async fn handle_invited_state(
&self,
room: &Room,
events: &[Raw<AnyStrippedStateEvent>],
events: &[(Raw<AnyStrippedStateEvent>, AnyStrippedStateEvent)],
push_rules: &Ruleset,
room_info: &mut RoomInfo,
changes: &mut StateChanges,
notifications: &mut BTreeMap<OwnedRoomId, Vec<Notification>>,
) -> Result<()> {
let mut state_events = BTreeMap::new();

for raw_event in events {
match raw_event.deserialize() {
Ok(e) => {
room_info.handle_stripped_state_event(&e);
state_events
.entry(e.event_type())
.or_insert_with(BTreeMap::new)
.insert(e.state_key().to_owned(), raw_event.clone());
}
Err(err) => {
warn!(
room_id = ?room_info.room_id,
"Couldn't deserialize stripped state event: {err:?}",
);
}
}
for (raw_event, event) in events {
room_info.handle_stripped_state_event(event);
state_events
.entry(event.event_type())
.or_insert_with(BTreeMap::new)
.insert(event.state_key().to_owned(), raw_event.clone());
}

changes.stripped_state.insert(room_info.room_id().to_owned(), state_events.clone());
Expand Down Expand Up @@ -1121,13 +1122,16 @@ impl BaseClient {
self.room_info_notable_update_sender.clone(),
);

let invite_state =
Self::deserialize_stripped_state_events(&new_info.invite_state.events);

let mut room_info = room.clone_info();
room_info.mark_as_invited();
room_info.mark_state_fully_synced();

self.handle_invited_state(
&room,
&new_info.invite_state.events,
&invite_state,
&push_rules,
&mut room_info,
&mut changes,
Expand All @@ -1140,6 +1144,34 @@ impl BaseClient {
new_rooms.invite.insert(room_id, new_info);
}

for (room_id, new_info) in response.rooms.knock {
let room = self.store.get_or_create_room(
&room_id,
RoomState::Knocked,
self.room_info_notable_update_sender.clone(),
);

let knock_state = Self::deserialize_stripped_state_events(&new_info.knock_state.events);

let mut room_info = room.clone_info();
room_info.mark_as_knocked();
room_info.mark_state_fully_synced();

self.handle_invited_state(
&room,
&knock_state,
&push_rules,
&mut room_info,
&mut changes,
&mut notifications,
)
.await?;

changes.add_room(room_info);

new_rooms.knocked.insert(room_id, new_info);
}

account_data_processor.apply(&mut changes, &self.store).await;

changes.presence = response
Expand Down Expand Up @@ -1582,6 +1614,21 @@ impl BaseClient {
.collect()
}

pub(crate) fn deserialize_stripped_state_events(
raw_events: &[Raw<AnyStrippedStateEvent>],
) -> Vec<(Raw<AnyStrippedStateEvent>, AnyStrippedStateEvent)> {
raw_events
.iter()
.filter_map(|raw_event| match raw_event.deserialize() {
Ok(event) => Some((raw_event.clone(), event)),
Err(e) => {
warn!("Couldn't deserialize stripped state event: {e}");
None
}
})
.collect()
}

/// Returns a new receiver that gets future room info notable updates.
///
/// Learn more by reading the [`RoomInfoNotableUpdate`] type.
Expand Down
19 changes: 18 additions & 1 deletion crates/matrix-sdk-base/src/debug.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,10 @@
use std::fmt;

pub use matrix_sdk_common::debug::*;
use ruma::{api::client::sync::sync_events::v3::InvitedRoom, serde::Raw};
use ruma::{
api::client::sync::sync_events::v3::{InvitedRoom, KnockedRoom},
serde::Raw,
};

/// A wrapper around a slice of `Raw` events that implements `Debug` in a way
/// that only prints the event type of each item.
Expand Down Expand Up @@ -46,6 +49,20 @@ impl<'a> fmt::Debug for DebugInvitedRoom<'a> {
}
}

/// A wrapper around a knocked on room as found in `/sync` responses that
/// implements `Debug` in a way that only prints the event ID and event type for
/// the raw events contained in `knock_state`.
pub struct DebugKnockedRoom<'a>(pub &'a KnockedRoom);

#[cfg(not(tarpaulin_include))]
impl<'a> fmt::Debug for DebugKnockedRoom<'a> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("KnockedRoom")
.field("knock_state", &DebugListOfRawEvents(&self.0.knock_state.events))
.finish()
}
}

pub(crate) struct DebugListOfRawEvents<'a, T>(pub &'a [Raw<T>]);

#[cfg(not(tarpaulin_include))]
Expand Down
Loading

0 comments on commit 664f6d5

Please sign in to comment.