Split sliding-sync into additional units.
Signed-off-by: Jason Volk <jason@zemos.net>
This commit is contained in:
@@ -1,50 +1,35 @@
|
||||
mod account_data;
|
||||
mod e2ee;
|
||||
mod extensions;
|
||||
mod filter;
|
||||
mod receipts;
|
||||
mod room;
|
||||
mod rooms;
|
||||
mod selector;
|
||||
mod to_device;
|
||||
mod typing;
|
||||
|
||||
use std::{collections::BTreeMap, fmt::Debug, time::Duration};
|
||||
|
||||
use axum::extract::State;
|
||||
use futures::{
|
||||
FutureExt, TryFutureExt, TryStreamExt,
|
||||
future::{OptionFuture, join, join5, try_join},
|
||||
FutureExt, TryFutureExt,
|
||||
future::{join, try_join},
|
||||
};
|
||||
use ruma::{
|
||||
DeviceId, OwnedRoomId, RoomId, UserId,
|
||||
api::client::sync::sync_events::v5::{
|
||||
ListId, Request, Response, request::ExtensionRoomConfig, response,
|
||||
},
|
||||
DeviceId, OwnedRoomId, UserId,
|
||||
api::client::sync::sync_events::v5::{ListId, Request, Response, response},
|
||||
events::room::member::MembershipState,
|
||||
};
|
||||
use tokio::time::{Instant, timeout_at};
|
||||
use tuwunel_core::{
|
||||
Err, Result, apply, at, debug,
|
||||
Err, Result, debug,
|
||||
debug::INFO_SPAN_LEVEL,
|
||||
debug_warn,
|
||||
error::inspect_log,
|
||||
extract_variant,
|
||||
smallvec::SmallVec,
|
||||
trace,
|
||||
utils::{
|
||||
BoolExt, IterStream, TryFutureExtExt,
|
||||
result::FlatOk,
|
||||
stream::{TryBroadbandExt, TryReadyExt},
|
||||
},
|
||||
utils::{TryFutureExtExt, result::FlatOk},
|
||||
};
|
||||
use tuwunel_service::{
|
||||
Services,
|
||||
sync::{Connection, into_connection_key},
|
||||
};
|
||||
|
||||
use self::{
|
||||
filter::{filter_room, filter_room_meta},
|
||||
selector::selector,
|
||||
};
|
||||
use super::share_encrypted_room;
|
||||
use crate::Ruma;
|
||||
|
||||
@@ -185,12 +170,15 @@ pub(crate) async fn sync_events_v5_route(
|
||||
);
|
||||
|
||||
conn.next_batch = services.globals.wait_pending().await?;
|
||||
(window, response.lists) = selector(&mut conn, sync_info).boxed().await;
|
||||
(window, response.lists) = selector::selector(&mut conn, sync_info)
|
||||
.boxed()
|
||||
.await;
|
||||
|
||||
if conn.globalsince < conn.next_batch {
|
||||
let rooms = handle_rooms(sync_info, &conn, &window)
|
||||
let rooms = rooms::handle(sync_info, &conn, &window)
|
||||
.map_ok(|response_rooms| response.rooms = response_rooms);
|
||||
|
||||
let extensions = handle_extensions(sync_info, &conn, &window)
|
||||
let extensions = extensions::handle(sync_info, &conn, &window)
|
||||
.map_ok(|response_extensions| response.extensions = response_extensions);
|
||||
|
||||
try_join(rooms, extensions).boxed().await?;
|
||||
@@ -233,161 +221,3 @@ pub(crate) async fn sync_events_v5_route(
|
||||
fn is_empty_response(response: &Response) -> bool {
|
||||
response.extensions.is_empty() && response.rooms.is_empty()
|
||||
}
|
||||
|
||||
#[tracing::instrument(
|
||||
name = "rooms",
|
||||
level = "debug",
|
||||
skip_all,
|
||||
fields(
|
||||
next_batch = conn.next_batch,
|
||||
window = window.len(),
|
||||
)
|
||||
)]
|
||||
async fn handle_rooms(
|
||||
sync_info: SyncInfo<'_>,
|
||||
conn: &Connection,
|
||||
window: &Window,
|
||||
) -> Result<BTreeMap<OwnedRoomId, response::Room>> {
|
||||
window
|
||||
.iter()
|
||||
.try_stream()
|
||||
.broad_and_then(async |(room_id, room)| {
|
||||
room::handle(sync_info, conn, room)
|
||||
.map_ok(|room| (room_id, room))
|
||||
.await
|
||||
})
|
||||
.ready_try_filter_map(|(room_id, room)| Ok(room.map(|room| (room_id, room))))
|
||||
.map_ok(|(room_id, room)| (room_id.to_owned(), room))
|
||||
.try_collect()
|
||||
.await
|
||||
}
|
||||
|
||||
#[tracing::instrument(
|
||||
name = "extensions",
|
||||
level = "debug",
|
||||
skip_all,
|
||||
fields(
|
||||
next_batch = conn.next_batch,
|
||||
window = window.len(),
|
||||
rooms = conn.rooms.len(),
|
||||
subs = conn.subscriptions.len(),
|
||||
)
|
||||
)]
|
||||
async fn handle_extensions(
|
||||
sync_info: SyncInfo<'_>,
|
||||
conn: &Connection,
|
||||
window: &Window,
|
||||
) -> Result<response::Extensions> {
|
||||
let SyncInfo { .. } = sync_info;
|
||||
|
||||
let account_data: OptionFuture<_> = conn
|
||||
.extensions
|
||||
.account_data
|
||||
.enabled
|
||||
.unwrap_or(false)
|
||||
.then(|| account_data::collect(sync_info, conn, window))
|
||||
.into();
|
||||
|
||||
let receipts: OptionFuture<_> = conn
|
||||
.extensions
|
||||
.receipts
|
||||
.enabled
|
||||
.unwrap_or(false)
|
||||
.then(|| receipts::collect(sync_info, conn, window))
|
||||
.into();
|
||||
|
||||
let typing: OptionFuture<_> = conn
|
||||
.extensions
|
||||
.typing
|
||||
.enabled
|
||||
.unwrap_or(false)
|
||||
.then(|| typing::collect(sync_info, conn, window))
|
||||
.into();
|
||||
|
||||
let to_device: OptionFuture<_> = conn
|
||||
.extensions
|
||||
.to_device
|
||||
.enabled
|
||||
.unwrap_or(false)
|
||||
.then(|| to_device::collect(sync_info, conn))
|
||||
.into();
|
||||
|
||||
let e2ee: OptionFuture<_> = conn
|
||||
.extensions
|
||||
.e2ee
|
||||
.enabled
|
||||
.unwrap_or(false)
|
||||
.then(|| e2ee::collect(sync_info, conn))
|
||||
.into();
|
||||
|
||||
let (account_data, receipts, typing, to_device, e2ee) =
|
||||
join5(account_data, receipts, typing, to_device, e2ee)
|
||||
.map(apply!(5, |t: Option<_>| t.unwrap_or(Ok(Default::default()))))
|
||||
.await;
|
||||
|
||||
Ok(response::Extensions {
|
||||
account_data: account_data?,
|
||||
receipts: receipts?,
|
||||
typing: typing?,
|
||||
to_device: to_device?,
|
||||
e2ee: e2ee?,
|
||||
})
|
||||
}
|
||||
|
||||
#[tracing::instrument(
|
||||
name = "selector",
|
||||
level = "trace",
|
||||
skip_all,
|
||||
fields(?implicit, ?explicit),
|
||||
)]
|
||||
fn extension_rooms_selector<'a, ListIter, SubsIter>(
|
||||
SyncInfo { .. }: SyncInfo<'a>,
|
||||
conn: &'a Connection,
|
||||
window: &'a Window,
|
||||
implicit: Option<ListIter>,
|
||||
explicit: Option<SubsIter>,
|
||||
) -> impl Iterator<Item = &'a RoomId> + Send + Sync + 'a
|
||||
where
|
||||
ListIter: Iterator<Item = &'a ListId> + Clone + Debug + Send + Sync + 'a,
|
||||
SubsIter: Iterator<Item = &'a ExtensionRoomConfig> + Clone + Debug + Send + Sync + 'a,
|
||||
{
|
||||
let has_all_subscribed = explicit
|
||||
.clone()
|
||||
.into_iter()
|
||||
.flatten()
|
||||
.any(|erc| matches!(erc, ExtensionRoomConfig::AllSubscribed));
|
||||
|
||||
let all_subscribed = has_all_subscribed
|
||||
.then(|| conn.subscriptions.keys())
|
||||
.into_iter()
|
||||
.flatten()
|
||||
.map(AsRef::as_ref);
|
||||
|
||||
let rooms_explicit = has_all_subscribed
|
||||
.is_false()
|
||||
.then(move || {
|
||||
explicit
|
||||
.into_iter()
|
||||
.flatten()
|
||||
.filter_map(|erc| extract_variant!(erc, ExtensionRoomConfig::Room))
|
||||
.map(AsRef::as_ref)
|
||||
})
|
||||
.into_iter()
|
||||
.flatten();
|
||||
|
||||
let rooms_selected = window
|
||||
.iter()
|
||||
.filter(move |(_, room)| {
|
||||
implicit.as_ref().is_none_or(|lists| {
|
||||
lists
|
||||
.clone()
|
||||
.any(|list| room.lists.contains(list))
|
||||
})
|
||||
})
|
||||
.map(at!(0))
|
||||
.map(AsRef::as_ref);
|
||||
|
||||
all_subscribed
|
||||
.chain(rooms_explicit)
|
||||
.chain(rooms_selected)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user