mirror of
https://github.com/matrix-org/matrix-rust-sdk.git
synced 2026-05-18 21:52:30 -04:00
Deserialise events early so we don't have to do it multiple times
We pass the already-deserialised event in to handle_state and process_sliding_sync_room_membership, to avoid deserialising inside both of them.
This commit is contained in:
@@ -17,7 +17,7 @@
|
||||
use std::ops::Deref;
|
||||
use std::{
|
||||
collections::{BTreeMap, BTreeSet},
|
||||
fmt,
|
||||
fmt, iter,
|
||||
sync::Arc,
|
||||
};
|
||||
|
||||
@@ -478,10 +478,16 @@ impl BaseClient {
|
||||
changes.stripped_state.insert(room_info.room_id().to_owned(), state_events);
|
||||
}
|
||||
|
||||
/// Process the events provided during a sync.
|
||||
///
|
||||
/// events must be exactly the same list of events that are in raw_events,
|
||||
/// but deserialised. We demand them here to avoid deserialising
|
||||
/// multiple times.
|
||||
#[instrument(skip_all, fields(room_id = ?room_info.room_id))]
|
||||
pub(crate) async fn handle_state(
|
||||
&self,
|
||||
events: &[Raw<AnySyncStateEvent>],
|
||||
raw_events: &[Raw<AnySyncStateEvent>],
|
||||
events: &[AnySyncStateEvent],
|
||||
room_info: &mut RoomInfo,
|
||||
changes: &mut StateChanges,
|
||||
ambiguity_cache: &mut AmbiguityCache,
|
||||
@@ -490,16 +496,8 @@ impl BaseClient {
|
||||
let mut user_ids = BTreeSet::new();
|
||||
let mut profiles = BTreeMap::new();
|
||||
|
||||
for raw_event in events {
|
||||
let event = match raw_event.deserialize() {
|
||||
Ok(ev) => ev,
|
||||
Err(e) => {
|
||||
warn!("Couldn't deserialize state event: {e}");
|
||||
continue;
|
||||
}
|
||||
};
|
||||
|
||||
room_info.handle_state_event(&event);
|
||||
for (raw_event, event) in iter::zip(raw_events, events) {
|
||||
room_info.handle_state_event(event);
|
||||
|
||||
if let AnySyncStateEvent::RoomMember(member) = &event {
|
||||
ambiguity_cache.handle_event(changes, &room_info.room_id, member).await?;
|
||||
@@ -714,9 +712,12 @@ impl BaseClient {
|
||||
room_info.set_prev_batch(new_info.timeline.prev_batch.as_deref());
|
||||
room_info.mark_state_fully_synced();
|
||||
|
||||
let deserialized_events = Self::deserialize_events(&new_info.state.events);
|
||||
|
||||
let mut user_ids = self
|
||||
.handle_state(
|
||||
&new_info.state.events,
|
||||
&deserialized_events,
|
||||
&mut room_info,
|
||||
&mut changes,
|
||||
&mut ambiguity_cache,
|
||||
@@ -800,9 +801,12 @@ impl BaseClient {
|
||||
room_info.mark_as_left();
|
||||
room_info.mark_state_partially_synced();
|
||||
|
||||
let deserialized_events = Self::deserialize_events(&new_info.state.events);
|
||||
|
||||
let mut user_ids = self
|
||||
.handle_state(
|
||||
&new_info.state.events,
|
||||
&deserialized_events,
|
||||
&mut room_info,
|
||||
&mut changes,
|
||||
&mut ambiguity_cache,
|
||||
@@ -1242,6 +1246,21 @@ impl BaseClient {
|
||||
pub fn subscribe_to_ignore_user_list_changes(&self) -> Subscriber<()> {
|
||||
self.ignore_user_list_changes_tx.subscribe()
|
||||
}
|
||||
|
||||
pub(crate) fn deserialize_events(
|
||||
raw_events: &[Raw<AnySyncStateEvent>],
|
||||
) -> Vec<AnySyncStateEvent> {
|
||||
raw_events
|
||||
.iter()
|
||||
.filter_map(|raw_event| match raw_event.deserialize() {
|
||||
Ok(ev) => Some(ev),
|
||||
Err(e) => {
|
||||
warn!("Couldn't deserialize state event: {e}");
|
||||
None
|
||||
}
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for BaseClient {
|
||||
|
||||
@@ -21,10 +21,9 @@ use ruma::{
|
||||
v4::{self, AccountData},
|
||||
},
|
||||
events::AnySyncStateEvent,
|
||||
serde::Raw,
|
||||
RoomId,
|
||||
};
|
||||
use tracing::{debug, info, instrument, warn};
|
||||
use tracing::{debug, info, instrument};
|
||||
|
||||
use super::BaseClient;
|
||||
#[cfg(feature = "e2e-encryption")]
|
||||
@@ -193,15 +192,30 @@ impl BaseClient {
|
||||
ambiguity_cache: &mut AmbiguityCache,
|
||||
account_data: &AccountData,
|
||||
) -> Result<(RoomInfo, Option<JoinedRoom>, Option<InvitedRoom>)> {
|
||||
let required_state = Self::deserialize_events(&room_data.required_state);
|
||||
|
||||
// Find or create the room in the store
|
||||
let (room, mut room_info, invited_room) =
|
||||
self.process_sliding_sync_room_membership(room_data, store, room_id, changes).await;
|
||||
let (room, mut room_info, invited_room) = self
|
||||
.process_sliding_sync_room_membership(
|
||||
room_data,
|
||||
&required_state,
|
||||
store,
|
||||
room_id,
|
||||
changes,
|
||||
)
|
||||
.await;
|
||||
|
||||
room_info.mark_state_partially_synced();
|
||||
|
||||
let mut user_ids = if !room_data.required_state.is_empty() {
|
||||
self.handle_state(&room_data.required_state, &mut room_info, changes, ambiguity_cache)
|
||||
.await?
|
||||
let mut user_ids = if !required_state.is_empty() {
|
||||
self.handle_state(
|
||||
&room_data.required_state,
|
||||
&required_state,
|
||||
&mut room_info,
|
||||
changes,
|
||||
ambiguity_cache,
|
||||
)
|
||||
.await?
|
||||
} else {
|
||||
Default::default()
|
||||
};
|
||||
@@ -276,6 +290,7 @@ impl BaseClient {
|
||||
async fn process_sliding_sync_room_membership(
|
||||
&self,
|
||||
room_data: &v4::SlidingSyncRoom,
|
||||
required_state: &[AnySyncStateEvent],
|
||||
store: &Store,
|
||||
room_id: &RoomId,
|
||||
changes: &mut StateChanges,
|
||||
@@ -319,31 +334,20 @@ impl BaseClient {
|
||||
// property. In sliding sync we only have invite_state and
|
||||
// required_state, so we must process required_state looking for
|
||||
// relevant membership events.
|
||||
self.handle_own_room_membership(&room_data.required_state, &mut room_info).await;
|
||||
self.handle_own_room_membership(required_state, &mut room_info).await;
|
||||
|
||||
(room, room_info, None)
|
||||
}
|
||||
}
|
||||
|
||||
/// Find any m.room.member events that refer to the current user, and update the state in
|
||||
/// room_info to reflect the "membership" property.
|
||||
/// Find any m.room.member events that refer to the current user, and update
|
||||
/// the state in room_info to reflect the "membership" property.
|
||||
pub(crate) async fn handle_own_room_membership(
|
||||
&self,
|
||||
required_state: &[Raw<AnySyncStateEvent>],
|
||||
required_state: &[AnySyncStateEvent],
|
||||
room_info: &mut RoomInfo,
|
||||
) {
|
||||
// Note: we deserialise these same events inside handle_state(). We could refactor to do
|
||||
// this only once.
|
||||
|
||||
for raw_event in required_state {
|
||||
let event = match raw_event.deserialize() {
|
||||
Ok(ev) => ev,
|
||||
Err(e) => {
|
||||
warn!("Couldn't deserialize state event: {e}");
|
||||
continue;
|
||||
}
|
||||
};
|
||||
|
||||
for event in required_state {
|
||||
if let AnySyncStateEvent::RoomMember(member) = &event {
|
||||
// If this event updates the current user's membership, record that in the
|
||||
// room_info.
|
||||
|
||||
Reference in New Issue
Block a user