mirror of
https://gitlab.computer.surgery/matrix/grapevine.git
synced 2025-12-18 08:11:24 +01:00
implement room.timeline.(not_)rooms filter on /sync
I asked in #matrix-spec:matrix.org and go clarification that we should be omitting the timeline field completely for rooms that are filtered out by the timeline.(not_)rooms filter. Ruma's skip_serializing_if attribute on the timeline field will currently cause it to be omitted when events is empty. If [this fix][1] is merged, it will be omitted only when events is empty, prev_batch is None, and limited is false. [1]: https://github.com/ruma/ruma/pull/1796 TODO: maybe do something about clippy::too_many_arguments
This commit is contained in:
parent
458d6842fb
commit
c48abf9f13
2 changed files with 37 additions and 12 deletions
|
|
@ -170,6 +170,7 @@ pub(crate) async fn sync_events_route(
|
|||
lazy_load_enabled,
|
||||
lazy_load_send_redundant,
|
||||
full_state,
|
||||
&compiled_filter,
|
||||
&mut device_list_updates,
|
||||
&mut left_encrypted_users,
|
||||
)
|
||||
|
|
@ -207,6 +208,7 @@ pub(crate) async fn sync_events_route(
|
|||
&next_batch_string,
|
||||
full_state,
|
||||
lazy_load_enabled,
|
||||
&compiled_filter,
|
||||
)
|
||||
.await?;
|
||||
}
|
||||
|
|
@ -382,9 +384,11 @@ async fn load_joined_room(
|
|||
lazy_load_enabled: bool,
|
||||
lazy_load_send_redundant: bool,
|
||||
full_state: bool,
|
||||
filter: &CompiledFilterDefinition<'_>,
|
||||
device_list_updates: &mut HashSet<OwnedUserId>,
|
||||
left_encrypted_users: &mut HashSet<OwnedUserId>,
|
||||
) -> Result<JoinedRoom> {
|
||||
// TODO: can we skip this when the room is filtered out?
|
||||
{
|
||||
// Get and drop the lock to wait for remaining operations to finish
|
||||
// This will make sure the we have all events until next_batch
|
||||
|
|
@ -402,7 +406,7 @@ async fn load_joined_room(
|
|||
}
|
||||
|
||||
let (timeline_pdus, limited) =
|
||||
load_timeline(sender_user, room_id, sincecount, 10)?;
|
||||
load_timeline(sender_user, room_id, sincecount, 10, Some(filter))?;
|
||||
|
||||
let send_notification_counts = !timeline_pdus.is_empty()
|
||||
|| services()
|
||||
|
|
@ -974,6 +978,7 @@ async fn load_joined_room(
|
|||
room_id = %room_id,
|
||||
),
|
||||
)]
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
async fn handle_left_room(
|
||||
room_id: OwnedRoomId,
|
||||
sender_user: &UserId,
|
||||
|
|
@ -982,6 +987,7 @@ async fn handle_left_room(
|
|||
next_batch_string: &str,
|
||||
full_state: bool,
|
||||
lazy_load_enabled: bool,
|
||||
filter: &CompiledFilterDefinition<'_>,
|
||||
) -> Result<()> {
|
||||
{
|
||||
// Get and drop the lock to wait for remaining operations to finish
|
||||
|
|
@ -1006,6 +1012,20 @@ async fn handle_left_room(
|
|||
return Ok(());
|
||||
}
|
||||
|
||||
let timeline = if filter.room.timeline.room_allowed(&room_id) {
|
||||
Timeline {
|
||||
limited: false,
|
||||
prev_batch: Some(next_batch_string.to_owned()),
|
||||
events: vec![],
|
||||
}
|
||||
} else {
|
||||
Timeline {
|
||||
limited: false,
|
||||
prev_batch: None,
|
||||
events: vec![],
|
||||
}
|
||||
};
|
||||
|
||||
if !services().rooms.metadata.exists(&room_id)? {
|
||||
// This is just a rejected invite, not a room we know
|
||||
let event = PduEvent {
|
||||
|
|
@ -1037,11 +1057,7 @@ async fn handle_left_room(
|
|||
account_data: RoomAccountData {
|
||||
events: Vec::new(),
|
||||
},
|
||||
timeline: Timeline {
|
||||
limited: false,
|
||||
prev_batch: Some(next_batch_string.to_owned()),
|
||||
events: Vec::new(),
|
||||
},
|
||||
timeline,
|
||||
state: State {
|
||||
events: vec![event.to_sync_state_event()],
|
||||
},
|
||||
|
|
@ -1126,11 +1142,7 @@ async fn handle_left_room(
|
|||
account_data: RoomAccountData {
|
||||
events: Vec::new(),
|
||||
},
|
||||
timeline: Timeline {
|
||||
limited: false,
|
||||
prev_batch: Some(next_batch_string.to_owned()),
|
||||
events: Vec::new(),
|
||||
},
|
||||
timeline,
|
||||
state: State {
|
||||
events: left_state_events,
|
||||
},
|
||||
|
|
@ -1145,9 +1157,17 @@ fn load_timeline(
|
|||
room_id: &RoomId,
|
||||
roomsincecount: PduCount,
|
||||
limit: u64,
|
||||
filter: Option<&CompiledFilterDefinition<'_>>,
|
||||
) -> Result<(Vec<(PduCount, PduEvent)>, bool), Error> {
|
||||
let timeline_pdus;
|
||||
let limited;
|
||||
|
||||
if let Some(filter) = filter {
|
||||
if !filter.room.timeline.room_allowed(room_id) {
|
||||
return Ok((vec![], false));
|
||||
}
|
||||
}
|
||||
|
||||
if services().rooms.timeline.last_timeline_count(sender_user, room_id)?
|
||||
> roomsincecount
|
||||
{
|
||||
|
|
@ -1622,6 +1642,7 @@ pub(crate) async fn sync_events_v4_route(
|
|||
room_id,
|
||||
roomsincecount,
|
||||
*timeline_limit,
|
||||
None,
|
||||
)?;
|
||||
|
||||
if roomsince != &0 && timeline_pdus.is_empty() {
|
||||
|
|
|
|||
|
|
@ -12,7 +12,9 @@
|
|||
//! In `/messages`, if the room is rejected by the filter, we can skip the
|
||||
//! entire request. The outer loop of our `/sync` implementation is over rooms,
|
||||
//! and so we are able to skip work for an entire room if it is rejected by the
|
||||
//! top-level `filter.rooms.room`.
|
||||
//! top-level `filter.rooms.room`. Similarly, when a room is rejected for all
|
||||
//! events in a particular category, we can skip work generating events in that
|
||||
//! category for the rejected room.
|
||||
|
||||
use std::{collections::HashSet, hash::Hash};
|
||||
|
||||
|
|
@ -156,6 +158,7 @@ pub(crate) struct CompiledFilterDefinition<'a> {
|
|||
|
||||
pub(crate) struct CompiledRoomFilter<'a> {
|
||||
rooms: AllowDenyList<'a, RoomId>,
|
||||
pub(crate) timeline: CompiledRoomEventFilter<'a>,
|
||||
}
|
||||
|
||||
pub(crate) struct CompiledRoomEventFilter<'a> {
|
||||
|
|
@ -193,6 +196,7 @@ impl<'a> TryFrom<&'a RoomFilter> for CompiledRoomFilter<'a> {
|
|||
source.rooms.as_deref(),
|
||||
&source.not_rooms,
|
||||
),
|
||||
timeline: (&source.timeline).try_into()?,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue