From 8f4fcf62999b598dccfe5ff4ab2c2ae5a677f039 Mon Sep 17 00:00:00 2001 From: Benjamin Bouvier Date: Tue, 1 Oct 2024 15:42:11 +0200 Subject: [PATCH] base: experiment with handling global account data as a separate processor --- crates/matrix-sdk-base/src/client.rs | 33 +---------- crates/matrix-sdk-base/src/lib.rs | 1 + .../src/response_processors.rs | 59 +++++++++++++++++++ .../matrix-sdk-base/src/sliding_sync/mod.rs | 5 +- 4 files changed, 65 insertions(+), 33 deletions(-) create mode 100644 crates/matrix-sdk-base/src/response_processors.rs diff --git a/crates/matrix-sdk-base/src/client.rs b/crates/matrix-sdk-base/src/client.rs index 648d83cf4..037abf1bc 100644 --- a/crates/matrix-sdk-base/src/client.rs +++ b/crates/matrix-sdk-base/src/client.rs @@ -72,6 +72,7 @@ use crate::{ deserialized_responses::{RawAnySyncOrStrippedTimelineEvent, SyncTimelineEvent}, error::{Error, Result}, event_cache_store::DynEventCacheStore, + response_processors::AccountDataProcessor, rooms::{ normal::{RoomInfoNotableUpdate, RoomInfoNotableUpdateReasons}, Room, RoomInfo, RoomState, @@ -688,36 +689,6 @@ impl BaseClient { } } - /// Parses and stores any raw global account data events into the - /// [`StateChanges`]. - /// - /// Returns a list with the parsed account data events. - #[instrument(skip_all)] - pub(crate) async fn handle_account_data( - &self, - events: &[Raw], - changes: &mut StateChanges, - ) -> Vec { - let mut account_data = BTreeMap::new(); - let mut parsed_events = Vec::new(); - - for raw_event in events { - let event = match raw_event.deserialize() { - Ok(e) => e, - Err(e) => { - let event_type: Option = raw_event.get_field("type").ok().flatten(); - warn!(event_type, "Failed to deserialize a global account data event: {e}"); - continue; - } - }; - account_data.insert(event.event_type(), raw_event.clone()); - parsed_events.push(event); - } - - changes.account_data = account_data; - parsed_events - } - /// Processes the direct rooms in a sync response: /// /// Given a [`StateChanges`] instance, processes any direct room info @@ -983,7 +954,7 @@ impl BaseClient { let mut ambiguity_cache = AmbiguityCache::new(self.store.inner.clone()); let global_account_data_events = - self.handle_account_data(&response.account_data.events, &mut changes).await; + ProcessAccountData::process(&response.account_data.events).apply(&mut changes); let push_rules = self.get_push_rules(&changes).await?; diff --git a/crates/matrix-sdk-base/src/lib.rs b/crates/matrix-sdk-base/src/lib.rs index e657fdd09..1b2fdbf65 100644 --- a/crates/matrix-sdk-base/src/lib.rs +++ b/crates/matrix-sdk-base/src/lib.rs @@ -31,6 +31,7 @@ pub mod event_cache_store; pub mod latest_event; pub mod media; pub mod notification_settings; +mod response_processors; mod rooms; pub mod read_receipts; diff --git a/crates/matrix-sdk-base/src/response_processors.rs b/crates/matrix-sdk-base/src/response_processors.rs new file mode 100644 index 000000000..25a8b253a --- /dev/null +++ b/crates/matrix-sdk-base/src/response_processors.rs @@ -0,0 +1,59 @@ +// Copyright 2024 The Matrix.org Foundation C.I.C. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +use std::{collections::BTreeMap, mem}; + +use ruma::{ + events::{AnyGlobalAccountDataEvent, GlobalAccountDataEventType}, + serde::Raw, +}; +use tracing::warn; + +use crate::StateChanges; + +#[must_use] +pub(crate) struct AccountDataProcessor { + parsed_events: Vec, + raw_by_type: BTreeMap>, +} + +impl AccountDataProcessor { + /// Creates a new processor for global account data. + pub fn process(events: &[Raw]) -> Self { + let mut raw_by_type = BTreeMap::new(); + let mut parsed_events = Vec::new(); + + for raw_event in events { + let event = match raw_event.deserialize() { + Ok(e) => e, + Err(e) => { + let event_type: Option = raw_event.get_field("type").ok().flatten(); + warn!(event_type, "Failed to deserialize a global account data event: {e}"); + continue; + } + }; + + raw_by_type.insert(event.event_type(), raw_event.clone()); + parsed_events.push(event); + } + + Self { raw_by_type, parsed_events } + } + + /// Applies the processed data to the state changes. + pub fn apply(mut self, changes: &mut StateChanges) -> Vec { + mem::swap(&mut changes.account_data, &mut self.raw_by_type); + self.parsed_events + } +} diff --git a/crates/matrix-sdk-base/src/sliding_sync/mod.rs b/crates/matrix-sdk-base/src/sliding_sync/mod.rs index a5b774bb1..680e0b37e 100644 --- a/crates/matrix-sdk-base/src/sliding_sync/mod.rs +++ b/crates/matrix-sdk-base/src/sliding_sync/mod.rs @@ -45,6 +45,7 @@ use crate::RoomMemberships; use crate::{ error::Result, read_receipts::{compute_unread_counts, PreviousEventsProvider}, + response_processors::AccountDataProcessor, rooms::{ normal::{RoomHero, RoomInfoNotableUpdateReasons}, RoomState, @@ -146,7 +147,7 @@ impl BaseClient { trace!( rooms = rooms.len(), lists = lists.len(), - extensions = !extensions.is_empty(), + has_extensions = !extensions.is_empty(), "Processing sliding sync room events" ); @@ -165,7 +166,7 @@ impl BaseClient { let account_data = &extensions.account_data; let global_account_data_events = if !account_data.is_empty() { - self.handle_account_data(&account_data.global, &mut changes).await + ProcessAccountData::process(&account_data.global).apply(&mut changes) } else { Vec::new() };