Services refactor

Replace structs of Dep<Service> with OnceServices, so each service has a Services reference

Remove service name => Service map

Flatten Services.rooms

Make reqwest Clients lazy initialized (client service)
This commit is contained in:
dasha_uwu
2025-08-22 20:15:54 +05:00
parent 26b3a84b88
commit b5890b9664
118 changed files with 457 additions and 1923 deletions

View File

@@ -46,7 +46,6 @@ pub(crate) async fn get_backfill_route(
.stream()
.filter_map(|event_id| {
services
.rooms
.timeline
.get_pdu_count(event_id)
.map(Result::ok)
@@ -60,13 +59,11 @@ pub(crate) async fn get_backfill_route(
origin: services.globals.server_name().to_owned(),
pdus: services
.rooms
.timeline
.pdus_rev(None, &body.room_id, Some(from.saturating_add(1)))
.try_take(limit)
.try_filter_map(async |(_, pdu)| {
Ok(services
.rooms
.state_accessor
.server_can_see_event(body.origin(), &pdu.room_id, &pdu.event_id)
.await
@@ -74,7 +71,6 @@ pub(crate) async fn get_backfill_route(
})
.try_filter_map(async |pdu| {
Ok(services
.rooms
.timeline
.get_pdu_json(&pdu.event_id)
.await

View File

@@ -16,7 +16,6 @@ pub(crate) async fn get_event_route(
body: Ruma<get_event::v1::Request>,
) -> Result<get_event::v1::Response> {
let event = services
.rooms
.timeline
.get_pdu_json(&body.event_id)
.await

View File

@@ -30,7 +30,6 @@ pub(crate) async fn get_event_authorization_route(
.await?;
let event = services
.rooms
.timeline
.get_pdu_json(&body.event_id)
.await
@@ -45,18 +44,10 @@ pub(crate) async fn get_event_authorization_route(
.map_err(|_| Error::bad_database("Invalid room_id in event in database."))?;
let auth_chain = services
.rooms
.auth_chain
.event_ids_iter(room_id, once(body.event_id.borrow()))
.ready_filter_map(Result::ok)
.filter_map(async |id| {
services
.rooms
.timeline
.get_pdu_json(&id)
.await
.ok()
})
.filter_map(async |id| services.timeline.get_pdu_json(&id).await.ok())
.then(|pdu| {
services
.sending

View File

@@ -38,12 +38,7 @@ pub(crate) async fn get_missing_events_route(
let mut i: usize = 0;
while i < queued_events.len() && events.len() < limit {
let Ok(pdu) = services
.rooms
.timeline
.get_pdu(&queued_events[i])
.await
else {
let Ok(pdu) = services.timeline.get_pdu(&queued_events[i]).await else {
debug!(
?body.origin,
"Event {} does not exist locally, skipping", &queued_events[i]
@@ -58,7 +53,6 @@ pub(crate) async fn get_missing_events_route(
}
if !services
.rooms
.state_accessor
.server_can_see_event(body.origin(), &body.room_id, &queued_events[i])
.await

View File

@@ -17,12 +17,7 @@ pub(crate) async fn get_hierarchy_route(
State(services): State<crate::State>,
body: Ruma<get_hierarchy::v1::Request>,
) -> Result<get_hierarchy::v1::Response> {
if !services
.rooms
.metadata
.exists(&body.room_id)
.await
{
if !services.metadata.exists(&body.room_id).await {
return Err!(Request(NotFound("Room does not exist.")));
}
@@ -30,7 +25,6 @@ pub(crate) async fn get_hierarchy_route(
let suggested_only = body.suggested_only;
let ref identifier = Identifier::ServerName(body.origin());
match services
.rooms
.spaces
.get_summary_and_children_local(room_id, identifier)
.await?
@@ -47,7 +41,6 @@ pub(crate) async fn get_hierarchy_route(
.stream()
.broad_filter_map(async |(child, _via)| {
match services
.rooms
.spaces
.get_summary_and_children_local(&child, identifier)
.await

View File

@@ -31,7 +31,6 @@ pub(crate) async fn create_invite_route(
) -> Result<create_invite::v2::Response> {
// ACL check origin
services
.rooms
.event_handler
.acl_check(body.origin(), &body.room_id)
.await?;
@@ -88,7 +87,6 @@ pub(crate) async fn create_invite_route(
// Make sure we're not ACL'ed from their room.
services
.rooms
.event_handler
.acl_check(invited_user.server_name(), &body.room_id)
.await?;
@@ -109,11 +107,8 @@ pub(crate) async fn create_invite_route(
.try_into()
.map_err(|e| err!(Request(InvalidParam("Invalid sender property: {e}"))))?;
if services
.rooms
.metadata
.is_banned(&body.room_id)
.await && !services.users.is_admin(&invited_user).await
if services.metadata.is_banned(&body.room_id).await
&& !services.users.is_admin(&invited_user).await
{
return Err!(Request(Forbidden("This room is banned on this homeserver.")));
}
@@ -144,13 +139,11 @@ pub(crate) async fn create_invite_route(
// record the invited state for client /sync through update_membership(), and
// send the invite PDU to the relevant appservices.
if !services
.rooms
.state_cache
.server_in_room(services.globals.server_name(), &body.room_id)
.await
{
services
.rooms
.state_cache
.update_membership(
&body.room_id,

View File

@@ -26,12 +26,7 @@ pub(crate) async fn create_join_event_template_route(
State(services): State<crate::State>,
body: Ruma<prepare_join_event::v1::Request>,
) -> Result<prepare_join_event::v1::Response> {
if !services
.rooms
.metadata
.exists(&body.room_id)
.await
{
if !services.metadata.exists(&body.room_id).await {
return Err!(Request(NotFound("Room is unknown to this server.")));
}
@@ -41,7 +36,6 @@ pub(crate) async fn create_join_event_template_route(
// ACL check origin server
services
.rooms
.event_handler
.acl_check(body.origin(), &body.room_id)
.await?;
@@ -74,7 +68,6 @@ pub(crate) async fn create_join_event_template_route(
}
let room_version_id = services
.rooms
.state
.get_room_version(&body.room_id)
.await?;
@@ -85,12 +78,7 @@ pub(crate) async fn create_join_event_template_route(
));
}
let state_lock = services
.rooms
.state
.mutex
.lock(&body.room_id)
.await;
let state_lock = services.state.mutex.lock(&body.room_id).await;
let join_authorized_via_users_server: Option<OwnedUserId> = {
use RoomVersionId::*;
@@ -106,11 +94,10 @@ pub(crate) async fn create_join_event_template_route(
.await?
{
let users = services
.rooms
.state_cache
.local_users_in_room(&body.room_id)
.filter(|user| {
services.rooms.state_accessor.user_can_invite(
services.state_accessor.user_can_invite(
&body.room_id,
user,
&body.user_id,
@@ -133,7 +120,6 @@ pub(crate) async fn create_join_event_template_route(
};
let (_pdu, mut pdu_json) = services
.rooms
.timeline
.create_hash_and_sign_event(
PduBuilder::state(body.user_id.to_string(), &RoomMemberEventContent {
@@ -172,7 +158,6 @@ pub(crate) async fn user_can_perform_restricted_join(
}
if services
.rooms
.state_cache
.is_joined(user_id, room_id)
.await
@@ -182,7 +167,6 @@ pub(crate) async fn user_can_perform_restricted_join(
}
let Ok(join_rules_event_content) = services
.rooms
.state_accessor
.room_state_get_content::<RoomJoinRulesEventContent>(
room_id,
@@ -217,7 +201,6 @@ pub(crate) async fn user_can_perform_restricted_join(
.stream()
.any(|m| {
services
.rooms
.state_cache
.is_joined(user_id, &m.room_id)
})

View File

@@ -17,12 +17,7 @@ pub(crate) async fn create_knock_event_template_route(
State(services): State<crate::State>,
body: Ruma<prepare_knock_event::v1::Request>,
) -> Result<prepare_knock_event::v1::Response> {
if !services
.rooms
.metadata
.exists(&body.room_id)
.await
{
if !services.metadata.exists(&body.room_id).await {
return Err!(Request(NotFound("Room is unknown to this server.")));
}
@@ -32,7 +27,6 @@ pub(crate) async fn create_knock_event_template_route(
// ACL check origin server
services
.rooms
.event_handler
.acl_check(body.origin(), &body.room_id)
.await?;
@@ -63,7 +57,6 @@ pub(crate) async fn create_knock_event_template_route(
}
let room_version_id = services
.rooms
.state
.get_room_version(&body.room_id)
.await?;
@@ -82,15 +75,9 @@ pub(crate) async fn create_knock_event_template_route(
));
}
let state_lock = services
.rooms
.state
.mutex
.lock(&body.room_id)
.await;
let state_lock = services.state.mutex.lock(&body.room_id).await;
if let Ok(membership) = services
.rooms
.state_accessor
.get_member(&body.room_id, &body.user_id)
.await
@@ -106,7 +93,6 @@ pub(crate) async fn create_knock_event_template_route(
}
let (_pdu, mut pdu_json) = services
.rooms
.timeline
.create_hash_and_sign_event(
PduBuilder::state(

View File

@@ -16,12 +16,7 @@ pub(crate) async fn create_leave_event_template_route(
State(services): State<crate::State>,
body: Ruma<prepare_leave_event::v1::Request>,
) -> Result<prepare_leave_event::v1::Response> {
if !services
.rooms
.metadata
.exists(&body.room_id)
.await
{
if !services.metadata.exists(&body.room_id).await {
return Err!(Request(NotFound("Room is unknown to this server.")));
}
@@ -33,25 +28,17 @@ pub(crate) async fn create_leave_event_template_route(
// ACL check origin
services
.rooms
.event_handler
.acl_check(body.origin(), &body.room_id)
.await?;
let room_version_id = services
.rooms
.state
.get_room_version(&body.room_id)
.await?;
let state_lock = services
.rooms
.state
.mutex
.lock(&body.room_id)
.await;
let state_lock = services.state.mutex.lock(&body.room_id).await;
let (_pdu, mut pdu_json) = services
.rooms
.timeline
.create_hash_and_sign_event(
PduBuilder::state(

View File

@@ -23,14 +23,12 @@ pub(crate) async fn get_room_information_route(
body: Ruma<get_room_information::v1::Request>,
) -> Result<get_room_information::v1::Response> {
let room_id = services
.rooms
.alias
.resolve_local_alias(&body.room_alias)
.await
.map_err(|_| err!(Request(NotFound("Room alias not found."))))?;
let mut servers: Vec<OwnedServerName> = services
.rooms
.state_cache
.room_servers(&room_id)
.map(ToOwned::to_owned)

View File

@@ -92,12 +92,7 @@ pub(crate) async fn send_transaction_message_route(
.pdus
.iter()
.stream()
.broad_then(|pdu| {
services
.rooms
.event_handler
.parse_incoming_pdu(pdu)
})
.broad_then(|pdu| services.event_handler.parse_incoming_pdu(pdu))
.inspect_err(|e| debug_warn!("Could not parse PDU: {e}"))
.ready_filter_map(Result::ok);
@@ -186,7 +181,6 @@ async fn handle_room(
pdus: impl Iterator<Item = Pdu> + Send,
) -> Result<ResolvedMap> {
let _room_lock = services
.rooms
.event_handler
.mutex_federation
.lock(room_id)
@@ -197,7 +191,6 @@ async fn handle_room(
services.server.check_running()?;
let pdu_start_time = Instant::now();
let result = services
.rooms
.event_handler
.handle_incoming_pdu(origin, &room_id, &event_id, value, true)
.map_ok(|_| ())
@@ -311,7 +304,6 @@ async fn handle_edu_receipt_room(
room_updates: ReceiptMap,
) {
if services
.rooms
.event_handler
.acl_check(origin, &room_id)
.await
@@ -351,7 +343,6 @@ async fn handle_edu_receipt_room_user(
}
if !services
.rooms
.state_cache
.server_in_room(origin, room_id)
.await
@@ -373,7 +364,6 @@ async fn handle_edu_receipt_room_user(
let receipts = [(ReceiptType::Read, BTreeMap::from(user_data))];
let content = [(event_id.clone(), BTreeMap::from(receipts))];
services
.rooms
.read_receipt
.readreceipt_update(user_id, room_id, &ReceiptEvent {
content: ReceiptEventContent(content.into()),
@@ -399,7 +389,6 @@ async fn handle_edu_typing(
}
if services
.rooms
.event_handler
.acl_check(typing.user_id.server_name(), &typing.room_id)
.await
@@ -413,7 +402,6 @@ async fn handle_edu_typing(
}
if !services
.rooms
.state_cache
.is_joined(&typing.user_id, &typing.room_id)
.await
@@ -430,7 +418,6 @@ async fn handle_edu_typing(
let timeout = millis_since_unix_epoch().saturating_add(secs.saturating_mul(1000));
services
.rooms
.typing
.typing_add(&typing.user_id, &typing.room_id, timeout)
.await
@@ -438,7 +425,6 @@ async fn handle_edu_typing(
.ok();
} else {
services
.rooms
.typing
.typing_remove(&typing.user_id, &typing.room_id)
.await

View File

@@ -31,13 +31,12 @@ async fn create_join_event(
room_id: &RoomId,
pdu: &RawJsonValue,
) -> Result<create_join_event::v1::RoomState> {
if !services.rooms.metadata.exists(room_id).await {
if !services.metadata.exists(room_id).await {
return Err!(Request(NotFound("Room is unknown to this server.")));
}
// ACL check origin server
services
.rooms
.event_handler
.acl_check(origin, room_id)
.await?;
@@ -45,7 +44,6 @@ async fn create_join_event(
// We need to return the state prior to joining, let's keep a reference to that
// here
let shortstatehash = services
.rooms
.state
.get_room_shortstatehash(room_id)
.await
@@ -53,11 +51,7 @@ async fn create_join_event(
// We do not add the event_id field to the pdu here because of signature and
// hashes checks
let room_version_id = services
.rooms
.state
.get_room_version(room_id)
.await?;
let room_version_id = services.state.get_room_version(room_id).await?;
let Ok((event_id, mut value)) = gen_event_id_canonical_json(pdu, &room_version_id) else {
// Event could not be converted to canonical json
@@ -118,7 +112,6 @@ async fn create_join_event(
.map_err(|e| err!(Request(BadJson(warn!("sender property is not a valid user ID: {e}")))))?;
services
.rooms
.event_handler
.acl_check(sender.server_name(), room_id)
.await?;
@@ -159,7 +152,6 @@ async fn create_join_event(
}
if !services
.rooms
.state_cache
.is_joined(&authorising_user, room_id)
.await
@@ -199,14 +191,12 @@ async fn create_join_event(
.map_err(|e| err!(Request(BadJson("Event has an invalid origin server name: {e}"))))?;
let mutex_lock = services
.rooms
.event_handler
.mutex_federation
.lock(room_id)
.await;
let pdu_id = services
.rooms
.event_handler
.handle_incoming_pdu(&origin, room_id, &event_id, value.clone(), true)
.boxed()
@@ -216,7 +206,6 @@ async fn create_join_event(
drop(mutex_lock);
let state_ids: Vec<OwnedEventId> = services
.rooms
.state_accessor
.state_full_ids(shortstatehash)
.map(at!(1))
@@ -226,7 +215,7 @@ async fn create_join_event(
let state = state_ids
.iter()
.try_stream()
.broad_and_then(|event_id| services.rooms.timeline.get_pdu_json(event_id))
.broad_and_then(|event_id| services.timeline.get_pdu_json(event_id))
.broad_and_then(|pdu| {
services
.sending
@@ -239,16 +228,9 @@ async fn create_join_event(
let starting_events = state_ids.iter().map(Borrow::borrow);
let auth_chain = services
.rooms
.auth_chain
.event_ids_iter(room_id, starting_events)
.broad_and_then(async |event_id| {
services
.rooms
.timeline
.get_pdu_json(&event_id)
.await
})
.broad_and_then(async |event_id| services.timeline.get_pdu_json(&event_id).await)
.broad_and_then(|pdu| {
services
.sending

View File

@@ -55,24 +55,17 @@ pub(crate) async fn create_knock_event_v1_route(
}
}
if !services
.rooms
.metadata
.exists(&body.room_id)
.await
{
if !services.metadata.exists(&body.room_id).await {
return Err!(Request(NotFound("Room is unknown to this server.")));
}
// ACL check origin server
services
.rooms
.event_handler
.acl_check(body.origin(), &body.room_id)
.await?;
let room_version_id = services
.rooms
.state
.get_room_version(&body.room_id)
.await?;
@@ -127,7 +120,6 @@ pub(crate) async fn create_knock_event_v1_route(
.map_err(|e| err!(Request(BadJson("Event sender is not a valid user ID: {e}"))))?;
services
.rooms
.event_handler
.acl_check(sender.server_name(), &body.room_id)
.await?;
@@ -168,14 +160,12 @@ pub(crate) async fn create_knock_event_v1_route(
.map_err(|e| err!(Request(InvalidParam("Invalid knock event PDU: {e}"))))?;
let mutex_lock = services
.rooms
.event_handler
.mutex_federation
.lock(&body.room_id)
.await;
let pdu_id = services
.rooms
.event_handler
.handle_incoming_pdu(&origin, &body.room_id, &event_id, value.clone(), true)
.boxed()
@@ -191,7 +181,6 @@ pub(crate) async fn create_knock_event_v1_route(
Ok(create_knock_event::v1::Response {
knock_room_state: services
.rooms
.state
.summary_stripped(&pdu)
.await

View File

@@ -46,24 +46,19 @@ async fn create_leave_event(
room_id: &RoomId,
pdu: &RawJsonValue,
) -> Result {
if !services.rooms.metadata.exists(room_id).await {
if !services.metadata.exists(room_id).await {
return Err!(Request(NotFound("Room is unknown to this server.")));
}
// ACL check origin
services
.rooms
.event_handler
.acl_check(origin, room_id)
.await?;
// We do not add the event_id field to the pdu here because of signature and
// hashes checks
let room_version_id = services
.rooms
.state
.get_room_version(room_id)
.await?;
let room_version_id = services.state.get_room_version(room_id).await?;
let Ok((event_id, value)) = gen_event_id_canonical_json(pdu, &room_version_id) else {
// Event could not be converted to canonical json
return Err!(Request(BadJson("Could not convert event to canonical json.")));
@@ -124,7 +119,6 @@ async fn create_leave_event(
.map_err(|e| err!(Request(BadJson(warn!("sender property is not a valid user ID: {e}")))))?;
services
.rooms
.event_handler
.acl_check(sender.server_name(), room_id)
.await?;
@@ -147,14 +141,12 @@ async fn create_leave_event(
}
let mutex_lock = services
.rooms
.event_handler
.mutex_federation
.lock(room_id)
.await;
let pdu_id = services
.rooms
.event_handler
.handle_incoming_pdu(origin, room_id, &event_id, value, true)
.boxed()

View File

@@ -25,14 +25,12 @@ pub(crate) async fn get_room_state_route(
.await?;
let shortstatehash = services
.rooms
.state_accessor
.pdu_shortstatehash(&body.event_id)
.await
.map_err(|_| err!(Request(NotFound("PDU state not found."))))?;
let state_ids: Vec<OwnedEventId> = services
.rooms
.state_accessor
.state_full_ids(shortstatehash)
.map(at!(1))
@@ -42,7 +40,7 @@ pub(crate) async fn get_room_state_route(
let pdus = state_ids
.iter()
.try_stream()
.and_then(|id| services.rooms.timeline.get_pdu_json(id))
.and_then(|id| services.timeline.get_pdu_json(id))
.and_then(|pdu| {
services
.sending
@@ -53,10 +51,9 @@ pub(crate) async fn get_room_state_route(
.await?;
let auth_chain = services
.rooms
.auth_chain
.event_ids_iter(&body.room_id, once(body.event_id.borrow()))
.and_then(async |id| services.rooms.timeline.get_pdu_json(&id).await)
.and_then(async |id| services.timeline.get_pdu_json(&id).await)
.and_then(|pdu| {
services
.sending

View File

@@ -26,14 +26,12 @@ pub(crate) async fn get_room_state_ids_route(
.await?;
let shortstatehash = services
.rooms
.state_accessor
.pdu_shortstatehash(&body.event_id)
.await
.map_err(|_| err!(Request(NotFound("Pdu state not found."))))?;
let pdu_ids: Vec<OwnedEventId> = services
.rooms
.state_accessor
.state_full_ids(shortstatehash)
.map(at!(1))
@@ -41,7 +39,6 @@ pub(crate) async fn get_room_state_ids_route(
.await;
let auth_chain_ids = services
.rooms
.auth_chain
.event_ids_iter(&body.room_id, once(body.event_id.borrow()))
.try_collect()

View File

@@ -14,20 +14,17 @@ pub(super) struct AccessCheck<'a> {
pub(super) async fn check(&self) -> Result {
let acl_check = self
.services
.rooms
.event_handler
.acl_check(self.origin, self.room_id)
.map(|result| result.is_ok());
let world_readable = self
.services
.rooms
.state_accessor
.is_world_readable(self.room_id);
let server_in_room = self
.services
.rooms
.state_cache
.server_in_room(self.origin, self.room_id);
@@ -35,7 +32,6 @@ pub(super) async fn check(&self) -> Result {
// acknowledge bans or leaves
let user_is_knocking = self
.services
.rooms
.state_cache
.room_members_knocked(self.room_id)
.count();
@@ -44,7 +40,6 @@ pub(super) async fn check(&self) -> Result {
.event_id
.map(|event_id| {
self.services
.rooms
.state_accessor
.server_can_see_event(self.origin, self.room_id, event_id)
})