refactor for stronger RawPduId type

implement standard traits for PduCount

enable serde for arrayvec

typedef various shortid's

pducount simplifications

split parts of pdu_metadata service to core/pdu and api/relations

remove some yields; improve var names/syntax

tweak types for limit timeline limit arguments

Signed-off-by: Jason Volk <jason@zemos.net>
This commit is contained in:
Jason Volk 2024-11-02 06:12:54 +00:00
parent 2e4d9cb37c
commit 9da523c004
41 changed files with 796 additions and 573 deletions

View file

@ -1,10 +1,7 @@
mod v3;
mod v4;
use conduit::{
utils::{math::usize_from_u64_truncated, ReadyExt},
PduCount,
};
use conduit::{utils::ReadyExt, PduCount};
use futures::StreamExt;
use ruma::{RoomId, UserId};
@ -12,7 +9,7 @@ pub(crate) use self::{v3::sync_events_route, v4::sync_events_v4_route};
use crate::{service::Services, Error, PduEvent, Result};
async fn load_timeline(
services: &Services, sender_user: &UserId, room_id: &RoomId, roomsincecount: PduCount, limit: u64,
services: &Services, sender_user: &UserId, room_id: &RoomId, roomsincecount: PduCount, limit: usize,
) -> Result<(Vec<(PduCount, PduEvent)>, bool), Error> {
let last_timeline_count = services
.rooms
@ -29,12 +26,12 @@ async fn load_timeline(
.timeline
.pdus_until(sender_user, room_id, PduCount::max())
.await?
.ready_take_while(|(pducount, _)| pducount > &roomsincecount);
.ready_take_while(|(pducount, _)| *pducount > roomsincecount);
// Take the last events for the timeline
let timeline_pdus: Vec<_> = non_timeline_pdus
.by_ref()
.take(usize_from_u64_truncated(limit))
.take(limit)
.collect::<Vec<_>>()
.await
.into_iter()

View file

@ -432,28 +432,26 @@ async fn handle_left_room(
left_state_ids.insert(leave_shortstatekey, left_event_id);
let mut i: u8 = 0;
for (key, id) in left_state_ids {
if full_state || since_state_ids.get(&key) != Some(&id) {
let (event_type, state_key) = services.rooms.short.get_statekey_from_short(key).await?;
for (shortstatekey, event_id) in left_state_ids {
if full_state || since_state_ids.get(&shortstatekey) != Some(&event_id) {
let (event_type, state_key) = services
.rooms
.short
.get_statekey_from_short(shortstatekey)
.await?;
// TODO: Delete "element_hacks" when this is resolved: https://github.com/vector-im/element-web/issues/22565
if !lazy_load_enabled
|| event_type != StateEventType::RoomMember
|| full_state
// TODO: Delete the following line when this is resolved: https://github.com/vector-im/element-web/issues/22565
|| (cfg!(feature = "element_hacks") && *sender_user == state_key)
|| event_type != StateEventType::RoomMember
|| full_state
|| (cfg!(feature = "element_hacks") && *sender_user == state_key)
{
let Ok(pdu) = services.rooms.timeline.get_pdu(&id).await else {
error!("Pdu in state not found: {}", id);
let Ok(pdu) = services.rooms.timeline.get_pdu(&event_id).await else {
error!("Pdu in state not found: {event_id}");
continue;
};
left_state_events.push(pdu.to_sync_state_event());
i = i.wrapping_add(1);
if i % 100 == 0 {
tokio::task::yield_now().await;
}
}
}
}
@ -542,7 +540,7 @@ async fn load_joined_room(
let insert_lock = services.rooms.timeline.mutex_insert.lock(room_id).await;
drop(insert_lock);
let (timeline_pdus, limited) = load_timeline(services, sender_user, room_id, sincecount, 10).await?;
let (timeline_pdus, limited) = load_timeline(services, sender_user, room_id, sincecount, 10_usize).await?;
let send_notification_counts = !timeline_pdus.is_empty()
|| services
@ -678,8 +676,7 @@ async fn load_joined_room(
let mut state_events = Vec::new();
let mut lazy_loaded = HashSet::new();
let mut i: u8 = 0;
for (shortstatekey, id) in current_state_ids {
for (shortstatekey, event_id) in current_state_ids {
let (event_type, state_key) = services
.rooms
.short
@ -687,24 +684,22 @@ async fn load_joined_room(
.await?;
if event_type != StateEventType::RoomMember {
let Ok(pdu) = services.rooms.timeline.get_pdu(&id).await else {
error!("Pdu in state not found: {id}");
let Ok(pdu) = services.rooms.timeline.get_pdu(&event_id).await else {
error!("Pdu in state not found: {event_id}");
continue;
};
state_events.push(pdu);
i = i.wrapping_add(1);
if i % 100 == 0 {
tokio::task::yield_now().await;
}
} else if !lazy_load_enabled
|| full_state
|| timeline_users.contains(&state_key)
// TODO: Delete the following line when this is resolved: https://github.com/vector-im/element-web/issues/22565
|| (cfg!(feature = "element_hacks") && *sender_user == state_key)
state_events.push(pdu);
continue;
}
// TODO: Delete "element_hacks" when this is resolved: https://github.com/vector-im/element-web/issues/22565
if !lazy_load_enabled
|| full_state || timeline_users.contains(&state_key)
|| (cfg!(feature = "element_hacks") && *sender_user == state_key)
{
let Ok(pdu) = services.rooms.timeline.get_pdu(&id).await else {
error!("Pdu in state not found: {id}");
let Ok(pdu) = services.rooms.timeline.get_pdu(&event_id).await else {
error!("Pdu in state not found: {event_id}");
continue;
};
@ -712,12 +707,8 @@ async fn load_joined_room(
if let Ok(uid) = UserId::parse(&state_key) {
lazy_loaded.insert(uid);
}
state_events.push(pdu);
i = i.wrapping_add(1);
if i % 100 == 0 {
tokio::task::yield_now().await;
}
state_events.push(pdu);
}
}

View file

@ -8,7 +8,7 @@ use axum::extract::State;
use conduit::{
debug, error, extract_variant,
utils::{
math::{ruma_from_usize, usize_from_ruma},
math::{ruma_from_usize, usize_from_ruma, usize_from_u64_truncated},
BoolExt, IterStream, ReadyExt, TryFutureExtExt,
},
warn, Error, PduCount, Result,
@ -350,14 +350,16 @@ pub(crate) async fn sync_events_v4_route(
new_known_rooms.extend(room_ids.iter().cloned());
for room_id in &room_ids {
let todo_room = todo_rooms
.entry(room_id.clone())
.or_insert((BTreeSet::new(), 0, u64::MAX));
let todo_room =
todo_rooms
.entry(room_id.clone())
.or_insert((BTreeSet::new(), 0_usize, u64::MAX));
let limit = list
let limit: usize = list
.room_details
.timeline_limit
.map_or(10, u64::from)
.map(u64::from)
.map_or(10, usize_from_u64_truncated)
.min(100);
todo_room
@ -406,8 +408,14 @@ pub(crate) async fn sync_events_v4_route(
}
let todo_room = todo_rooms
.entry(room_id.clone())
.or_insert((BTreeSet::new(), 0, u64::MAX));
let limit = room.timeline_limit.map_or(10, u64::from).min(100);
.or_insert((BTreeSet::new(), 0_usize, u64::MAX));
let limit: usize = room
.timeline_limit
.map(u64::from)
.map_or(10, usize_from_u64_truncated)
.min(100);
todo_room.0.extend(room.required_state.iter().cloned());
todo_room.1 = todo_room.1.max(limit);
// 0 means unknown because it got out of date