mirror of
https://gitlab.computer.surgery/matrix/grapevine.git
synced 2025-12-19 00:31: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_enabled,
|
||||||
lazy_load_send_redundant,
|
lazy_load_send_redundant,
|
||||||
full_state,
|
full_state,
|
||||||
|
&compiled_filter,
|
||||||
&mut device_list_updates,
|
&mut device_list_updates,
|
||||||
&mut left_encrypted_users,
|
&mut left_encrypted_users,
|
||||||
)
|
)
|
||||||
|
|
@ -207,6 +208,7 @@ pub(crate) async fn sync_events_route(
|
||||||
&next_batch_string,
|
&next_batch_string,
|
||||||
full_state,
|
full_state,
|
||||||
lazy_load_enabled,
|
lazy_load_enabled,
|
||||||
|
&compiled_filter,
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
}
|
}
|
||||||
|
|
@ -382,9 +384,11 @@ async fn load_joined_room(
|
||||||
lazy_load_enabled: bool,
|
lazy_load_enabled: bool,
|
||||||
lazy_load_send_redundant: bool,
|
lazy_load_send_redundant: bool,
|
||||||
full_state: bool,
|
full_state: bool,
|
||||||
|
filter: &CompiledFilterDefinition<'_>,
|
||||||
device_list_updates: &mut HashSet<OwnedUserId>,
|
device_list_updates: &mut HashSet<OwnedUserId>,
|
||||||
left_encrypted_users: &mut HashSet<OwnedUserId>,
|
left_encrypted_users: &mut HashSet<OwnedUserId>,
|
||||||
) -> Result<JoinedRoom> {
|
) -> 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
|
// Get and drop the lock to wait for remaining operations to finish
|
||||||
// This will make sure the we have all events until next_batch
|
// 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) =
|
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()
|
let send_notification_counts = !timeline_pdus.is_empty()
|
||||||
|| services()
|
|| services()
|
||||||
|
|
@ -974,6 +978,7 @@ async fn load_joined_room(
|
||||||
room_id = %room_id,
|
room_id = %room_id,
|
||||||
),
|
),
|
||||||
)]
|
)]
|
||||||
|
#[allow(clippy::too_many_arguments)]
|
||||||
async fn handle_left_room(
|
async fn handle_left_room(
|
||||||
room_id: OwnedRoomId,
|
room_id: OwnedRoomId,
|
||||||
sender_user: &UserId,
|
sender_user: &UserId,
|
||||||
|
|
@ -982,6 +987,7 @@ async fn handle_left_room(
|
||||||
next_batch_string: &str,
|
next_batch_string: &str,
|
||||||
full_state: bool,
|
full_state: bool,
|
||||||
lazy_load_enabled: bool,
|
lazy_load_enabled: bool,
|
||||||
|
filter: &CompiledFilterDefinition<'_>,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
{
|
{
|
||||||
// Get and drop the lock to wait for remaining operations to finish
|
// Get and drop the lock to wait for remaining operations to finish
|
||||||
|
|
@ -1006,6 +1012,20 @@ async fn handle_left_room(
|
||||||
return Ok(());
|
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)? {
|
if !services().rooms.metadata.exists(&room_id)? {
|
||||||
// This is just a rejected invite, not a room we know
|
// This is just a rejected invite, not a room we know
|
||||||
let event = PduEvent {
|
let event = PduEvent {
|
||||||
|
|
@ -1037,11 +1057,7 @@ async fn handle_left_room(
|
||||||
account_data: RoomAccountData {
|
account_data: RoomAccountData {
|
||||||
events: Vec::new(),
|
events: Vec::new(),
|
||||||
},
|
},
|
||||||
timeline: Timeline {
|
timeline,
|
||||||
limited: false,
|
|
||||||
prev_batch: Some(next_batch_string.to_owned()),
|
|
||||||
events: Vec::new(),
|
|
||||||
},
|
|
||||||
state: State {
|
state: State {
|
||||||
events: vec![event.to_sync_state_event()],
|
events: vec![event.to_sync_state_event()],
|
||||||
},
|
},
|
||||||
|
|
@ -1126,11 +1142,7 @@ async fn handle_left_room(
|
||||||
account_data: RoomAccountData {
|
account_data: RoomAccountData {
|
||||||
events: Vec::new(),
|
events: Vec::new(),
|
||||||
},
|
},
|
||||||
timeline: Timeline {
|
timeline,
|
||||||
limited: false,
|
|
||||||
prev_batch: Some(next_batch_string.to_owned()),
|
|
||||||
events: Vec::new(),
|
|
||||||
},
|
|
||||||
state: State {
|
state: State {
|
||||||
events: left_state_events,
|
events: left_state_events,
|
||||||
},
|
},
|
||||||
|
|
@ -1145,9 +1157,17 @@ fn load_timeline(
|
||||||
room_id: &RoomId,
|
room_id: &RoomId,
|
||||||
roomsincecount: PduCount,
|
roomsincecount: PduCount,
|
||||||
limit: u64,
|
limit: u64,
|
||||||
|
filter: Option<&CompiledFilterDefinition<'_>>,
|
||||||
) -> Result<(Vec<(PduCount, PduEvent)>, bool), Error> {
|
) -> Result<(Vec<(PduCount, PduEvent)>, bool), Error> {
|
||||||
let timeline_pdus;
|
let timeline_pdus;
|
||||||
let limited;
|
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)?
|
if services().rooms.timeline.last_timeline_count(sender_user, room_id)?
|
||||||
> roomsincecount
|
> roomsincecount
|
||||||
{
|
{
|
||||||
|
|
@ -1622,6 +1642,7 @@ pub(crate) async fn sync_events_v4_route(
|
||||||
room_id,
|
room_id,
|
||||||
roomsincecount,
|
roomsincecount,
|
||||||
*timeline_limit,
|
*timeline_limit,
|
||||||
|
None,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
if roomsince != &0 && timeline_pdus.is_empty() {
|
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
|
//! 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,
|
//! 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
|
//! 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};
|
use std::{collections::HashSet, hash::Hash};
|
||||||
|
|
||||||
|
|
@ -156,6 +158,7 @@ pub(crate) struct CompiledFilterDefinition<'a> {
|
||||||
|
|
||||||
pub(crate) struct CompiledRoomFilter<'a> {
|
pub(crate) struct CompiledRoomFilter<'a> {
|
||||||
rooms: AllowDenyList<'a, RoomId>,
|
rooms: AllowDenyList<'a, RoomId>,
|
||||||
|
pub(crate) timeline: CompiledRoomEventFilter<'a>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) struct CompiledRoomEventFilter<'a> {
|
pub(crate) struct CompiledRoomEventFilter<'a> {
|
||||||
|
|
@ -193,6 +196,7 @@ impl<'a> TryFrom<&'a RoomFilter> for CompiledRoomFilter<'a> {
|
||||||
source.rooms.as_deref(),
|
source.rooms.as_deref(),
|
||||||
&source.not_rooms,
|
&source.not_rooms,
|
||||||
),
|
),
|
||||||
|
timeline: (&source.timeline).try_into()?,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue