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

@@ -20,22 +20,15 @@ pub(crate) async fn ban_user_route(
return Err!(Request(Forbidden("You cannot ban yourself.")));
}
let state_lock = services
.rooms
.state
.mutex
.lock(&body.room_id)
.await;
let state_lock = services.state.mutex.lock(&body.room_id).await;
let current_member_content = services
.rooms
.state_accessor
.get_member(&body.room_id, &body.user_id)
.await
.unwrap_or_else(|_| RoomMemberEventContent::new(MembershipState::Ban));
services
.rooms
.timeline
.build_and_append_pdu(
PduBuilder::state(body.user_id.to_string(), &RoomMemberEventContent {

View File

@@ -21,18 +21,9 @@ pub(crate) async fn forget_room_route(
let user_id = body.sender_user();
let room_id = &body.room_id;
let joined = services
.rooms
.state_cache
.is_joined(user_id, room_id);
let knocked = services
.rooms
.state_cache
.is_knocked(user_id, room_id);
let invited = services
.rooms
.state_cache
.is_invited(user_id, room_id);
let joined = services.state_cache.is_joined(user_id, room_id);
let knocked = services.state_cache.is_knocked(user_id, room_id);
let invited = services.state_cache.is_invited(user_id, room_id);
pin_mut!(joined, knocked, invited);
if joined.or(knocked).or(invited).await {
@@ -40,7 +31,6 @@ pub(crate) async fn forget_room_route(
}
let membership = services
.rooms
.state_accessor
.get_member(room_id, user_id)
.await;
@@ -55,15 +45,11 @@ pub(crate) async fn forget_room_route(
if non_membership
|| services
.rooms
.state_cache
.is_left(user_id, room_id)
.await
{
services
.rooms
.state_cache
.forget(room_id, user_id);
services.state_cache.forget(room_id, user_id);
}
Ok(forget_room::v3::Response::new())

View File

@@ -61,7 +61,6 @@ pub(crate) async fn invite_user_route(
}
if let Ok(target_user_membership) = services
.rooms
.state_accessor
.get_member(&body.room_id, user_id)
.await
@@ -111,7 +110,7 @@ pub(crate) async fn invite_helper(
if !services.globals.user_is_local(user_id) {
let (pdu, pdu_json, invite_room_state) = {
let state_lock = services.rooms.state.mutex.lock(room_id).await;
let state_lock = services.state.mutex.lock(room_id).await;
let content = RoomMemberEventContent {
avatar_url: services.users.avatar_url(user_id).await.ok(),
@@ -121,7 +120,6 @@ pub(crate) async fn invite_helper(
};
let (pdu, pdu_json) = services
.rooms
.timeline
.create_hash_and_sign_event(
PduBuilder::state(user_id.to_string(), &content),
@@ -131,18 +129,14 @@ pub(crate) async fn invite_helper(
)
.await?;
let invite_room_state = services.rooms.state.summary_stripped(&pdu).await;
let invite_room_state = services.state.summary_stripped(&pdu).await;
drop(state_lock);
(pdu, pdu_json, invite_room_state)
};
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 response = services
.sending
@@ -159,7 +153,6 @@ pub(crate) async fn invite_helper(
.map(Into::into)
.collect(),
via: services
.rooms
.state_cache
.servers_route_via(room_id)
.await
@@ -192,7 +185,6 @@ pub(crate) async fn invite_helper(
})?;
let pdu_id = services
.rooms
.event_handler
.handle_incoming_pdu(&origin, room_id, &event_id, value, true)
.boxed()
@@ -208,7 +200,6 @@ pub(crate) async fn invite_helper(
}
if !services
.rooms
.state_cache
.is_joined(sender_user, room_id)
.await
@@ -218,7 +209,7 @@ pub(crate) async fn invite_helper(
)));
}
let state_lock = services.rooms.state.mutex.lock(room_id).await;
let state_lock = services.state.mutex.lock(room_id).await;
let content = RoomMemberEventContent {
displayname: services.users.displayname(user_id).await.ok(),
@@ -230,7 +221,6 @@ pub(crate) async fn invite_helper(
};
services
.rooms
.timeline
.build_and_append_pdu(
PduBuilder::state(user_id.to_string(), &content),

View File

@@ -76,7 +76,6 @@ pub(crate) async fn join_room_by_id_route(
// There is no body.server_name for /roomId/join
let mut servers: Vec<_> = services
.rooms
.state_cache
.servers_invite_via(&body.room_id)
.map(ToOwned::to_owned)
@@ -85,7 +84,6 @@ pub(crate) async fn join_room_by_id_route(
servers.extend(
services
.rooms
.state_cache
.invite_state(sender_user, &body.room_id)
.await
@@ -151,7 +149,6 @@ pub(crate) async fn join_room_by_id_or_alias_route(
let mut servers = body.via.clone();
servers.extend(
services
.rooms
.state_cache
.servers_invite_via(&room_id)
.map(ToOwned::to_owned)
@@ -161,7 +158,6 @@ pub(crate) async fn join_room_by_id_or_alias_route(
servers.extend(
services
.rooms
.state_cache
.invite_state(sender_user, &room_id)
.await
@@ -184,7 +180,6 @@ pub(crate) async fn join_room_by_id_or_alias_route(
},
| Err(room_alias) => {
let (room_id, mut servers) = services
.rooms
.alias
.resolve_alias(&room_alias, Some(body.via.clone()))
.await?;
@@ -199,13 +194,11 @@ pub(crate) async fn join_room_by_id_or_alias_route(
.await?;
let addl_via_servers = services
.rooms
.state_cache
.servers_invite_via(&room_id)
.map(ToOwned::to_owned);
let addl_state_servers = services
.rooms
.state_cache
.invite_state(sender_user, &room_id)
.await
@@ -254,7 +247,7 @@ pub async fn join_room_by_id_helper(
third_party_signed: Option<&ThirdPartySigned>,
appservice_info: &Option<RegistrationInfo>,
) -> Result<join_room_by_id::v3::Response> {
let state_lock = services.rooms.state.mutex.lock(room_id).await;
let state_lock = services.state.mutex.lock(room_id).await;
let user_is_guest = services
.users
@@ -265,7 +258,6 @@ pub async fn join_room_by_id_helper(
if user_is_guest
&& !services
.rooms
.state_accessor
.guest_can_join(room_id)
.await
@@ -274,7 +266,6 @@ pub async fn join_room_by_id_helper(
}
if services
.rooms
.state_cache
.is_joined(sender_user, room_id)
.await
@@ -284,7 +275,6 @@ pub async fn join_room_by_id_helper(
}
if let Ok(membership) = services
.rooms
.state_accessor
.get_member(room_id, sender_user)
.await
@@ -296,7 +286,6 @@ pub async fn join_room_by_id_helper(
}
let server_in_room = services
.rooms
.state_cache
.server_in_room(services.globals.server_name(), room_id)
.await;
@@ -518,7 +507,6 @@ async fn join_room_by_id_helper_remote(
}
services
.rooms
.short
.get_or_create_shortroomid(room_id)
.await;
@@ -565,13 +553,11 @@ async fn join_room_by_id_helper_remote(
};
services
.rooms
.timeline
.add_pdu_outlier(&event_id, &value);
if let Some(state_key) = &pdu.state_key {
let shortstatekey = services
.rooms
.short
.get_or_create_shortstatekey(&pdu.kind.to_string().into(), state_key)
.await;
@@ -600,7 +586,6 @@ async fn join_room_by_id_helper_remote(
.ready_filter_map(Result::ok)
.ready_for_each(|(event_id, value)| {
services
.rooms
.timeline
.add_pdu_outlier(&event_id, &value);
})
@@ -612,10 +597,9 @@ async fn join_room_by_id_helper_remote(
state_res::auth_check(
&room_version::rules(&room_version_id)?,
&parsed_join_pdu,
&async |event_id| services.rooms.timeline.get_pdu(&event_id).await,
&async |event_id| services.timeline.get_pdu(&event_id).await,
&async |event_type, state_key| {
let shortstatekey = services
.rooms
.short
.get_shortstatekey(&event_type, state_key.as_str())
.await?;
@@ -624,7 +608,7 @@ async fn join_room_by_id_helper_remote(
err!(Request(NotFound("Missing fetch_state {shortstatekey:?}")))
})?;
services.rooms.timeline.get_pdu(event_id).await
services.timeline.get_pdu(event_id).await
},
)
.boxed()
@@ -632,7 +616,6 @@ async fn join_room_by_id_helper_remote(
info!("Compressing state from send_join");
let compressed: CompressedState = services
.rooms
.state_compressor
.compress_state_events(state.iter().map(|(ssk, eid)| (ssk, eid.borrow())))
.collect()
@@ -644,21 +627,18 @@ async fn join_room_by_id_helper_remote(
added,
removed,
} = services
.rooms
.state_compressor
.save_state(room_id, Arc::new(compressed))
.await?;
debug!("Forcing state for new room");
services
.rooms
.state
.force_state(room_id, statehash_before_join, added, removed, &state_lock)
.await?;
info!("Updating joined counts for new room");
services
.rooms
.state_cache
.update_joined_count(room_id)
.await;
@@ -667,14 +647,12 @@ async fn join_room_by_id_helper_remote(
// time with the pdu without it's state. This is okay because append_pdu can't
// fail.
let statehash_after_join = services
.rooms
.state
.append_to_state(&parsed_join_pdu)
.await?;
info!("Appending new room join event");
services
.rooms
.timeline
.append_pdu(
&parsed_join_pdu,
@@ -688,7 +666,6 @@ async fn join_room_by_id_helper_remote(
// We set the room state after inserting the pdu, so that we never have a moment
// in time where events in the current room state do not exist
services
.rooms
.state
.set_room_state(room_id, statehash_after_join, &state_lock);
@@ -708,7 +685,6 @@ async fn join_room_by_id_helper_local(
debug_info!("We can join locally");
let join_rules_event_content = services
.rooms
.state_accessor
.room_state_get_content::<RoomJoinRulesEventContent>(
room_id,
@@ -737,18 +713,16 @@ async fn join_room_by_id_helper_local(
.stream()
.any(|restriction_room_id| {
services
.rooms
.state_cache
.is_joined(sender_user, restriction_room_id)
})
.await
{
let users = services
.rooms
.state_cache
.local_users_in_room(room_id)
.filter(|user| {
services.rooms.state_accessor.user_can_invite(
services.state_accessor.user_can_invite(
room_id,
user,
sender_user,
@@ -775,7 +749,6 @@ async fn join_room_by_id_helper_local(
// Try normal join first
let Err(error) = services
.rooms
.timeline
.build_and_append_pdu(
PduBuilder::state(sender_user.to_string(), &content),
@@ -912,7 +885,6 @@ async fn join_room_by_id_helper_local(
drop(state_lock);
services
.rooms
.event_handler
.handle_incoming_pdu(&remote_server, room_id, &signed_event_id, signed_value, true)
.boxed()

View File

@@ -14,15 +14,9 @@ pub(crate) async fn kick_user_route(
State(services): State<crate::State>,
body: Ruma<kick_user::v3::Request>,
) -> Result<kick_user::v3::Response> {
let state_lock = services
.rooms
.state
.mutex
.lock(&body.room_id)
.await;
let state_lock = services.state.mutex.lock(&body.room_id).await;
let Ok(event) = services
.rooms
.state_accessor
.get_member(&body.room_id, &body.user_id)
.await
@@ -43,7 +37,6 @@ pub(crate) async fn kick_user_route(
}
services
.rooms
.timeline
.build_and_append_pdu(
PduBuilder::state(body.user_id.to_string(), &RoomMemberEventContent {

View File

@@ -67,7 +67,6 @@ pub(crate) async fn knock_room_route(
let mut servers = body.via.clone();
servers.extend(
services
.rooms
.state_cache
.servers_invite_via(&room_id)
.map(ToOwned::to_owned)
@@ -77,7 +76,6 @@ pub(crate) async fn knock_room_route(
servers.extend(
services
.rooms
.state_cache
.invite_state(sender_user, &room_id)
.await
@@ -100,7 +98,6 @@ pub(crate) async fn knock_room_route(
},
| Err(room_alias) => {
let (room_id, mut servers) = services
.rooms
.alias
.resolve_alias(&room_alias, Some(body.via.clone()))
.await?;
@@ -115,13 +112,11 @@ pub(crate) async fn knock_room_route(
.await?;
let addl_via_servers = services
.rooms
.state_cache
.servers_invite_via(&room_id)
.map(ToOwned::to_owned);
let addl_state_servers = services
.rooms
.state_cache
.invite_state(sender_user, &room_id)
.await
@@ -158,10 +153,9 @@ async fn knock_room_by_id_helper(
reason: Option<String>,
servers: &[OwnedServerName],
) -> Result<knock_room::v3::Response> {
let state_lock = services.rooms.state.mutex.lock(room_id).await;
let state_lock = services.state.mutex.lock(room_id).await;
if services
.rooms
.state_cache
.is_invited(sender_user, room_id)
.await
@@ -173,7 +167,6 @@ async fn knock_room_by_id_helper(
}
if services
.rooms
.state_cache
.is_joined(sender_user, room_id)
.await
@@ -183,7 +176,6 @@ async fn knock_room_by_id_helper(
}
if services
.rooms
.state_cache
.is_knocked(sender_user, room_id)
.await
@@ -193,7 +185,6 @@ async fn knock_room_by_id_helper(
}
if let Ok(membership) = services
.rooms
.state_accessor
.get_member(room_id, sender_user)
.await
@@ -205,7 +196,6 @@ async fn knock_room_by_id_helper(
}
let server_in_room = services
.rooms
.state_cache
.server_in_room(services.globals.server_name(), room_id)
.await;
@@ -237,11 +227,7 @@ async fn knock_room_helper_local(
) -> Result {
debug_info!("We can knock locally");
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?;
if matches!(
room_version_id,
@@ -265,7 +251,6 @@ async fn knock_room_helper_local(
// Try normal knock first
let Err(error) = services
.rooms
.timeline
.build_and_append_pdu(
PduBuilder::state(sender_user.to_string(), &content),
@@ -366,7 +351,6 @@ async fn knock_room_helper_local(
info!("send_knock finished");
services
.rooms
.short
.get_or_create_shortroomid(room_id)
.await;
@@ -378,7 +362,6 @@ async fn knock_room_helper_local(
info!("Updating membership locally to knock state with provided stripped state events");
services
.rooms
.state_cache
.update_membership(
room_id,
@@ -401,7 +384,6 @@ async fn knock_room_helper_local(
info!("Appending room knock event locally");
services
.rooms
.timeline
.append_pdu(
&parsed_knock_pdu,
@@ -503,7 +485,6 @@ async fn knock_room_helper_remote(
info!("send_knock finished");
services
.rooms
.short
.get_or_create_shortroomid(room_id)
.await;
@@ -550,13 +531,11 @@ async fn knock_room_helper_remote(
let event_id = gen_event_id(&event, &room_version_id)?;
let shortstatekey = services
.rooms
.short
.get_or_create_shortstatekey(&event_type, &state_key)
.await;
services
.rooms
.timeline
.add_pdu_outlier(&event_id, &event);
@@ -565,7 +544,6 @@ async fn knock_room_helper_remote(
info!("Compressing state from send_knock");
let compressed: CompressedState = services
.rooms
.state_compressor
.compress_state_events(
state_map
@@ -581,27 +559,23 @@ async fn knock_room_helper_remote(
added,
removed,
} = services
.rooms
.state_compressor
.save_state(room_id, Arc::new(compressed))
.await?;
debug!("Forcing state for new room");
services
.rooms
.state
.force_state(room_id, statehash_before_knock, added, removed, &state_lock)
.await?;
let statehash_after_knock = services
.rooms
.state
.append_to_state(&parsed_knock_pdu)
.await?;
info!("Updating membership locally to knock state with provided stripped state events");
services
.rooms
.state_cache
.update_membership(
room_id,
@@ -624,7 +598,6 @@ async fn knock_room_helper_remote(
info!("Appending room knock event locally");
services
.rooms
.timeline
.append_pdu(
&parsed_knock_pdu,
@@ -638,7 +611,6 @@ async fn knock_room_helper_remote(
// We set the room state after inserting the pdu, so that we never have a moment
// in time where events in the current room state do not exist
services
.rooms
.state
.set_room_state(room_id, statehash_after_knock, &state_lock);

View File

@@ -42,19 +42,16 @@ pub(crate) async fn leave_room_route(
// and ignores errors
pub async fn leave_all_rooms(services: &Services, user_id: &UserId) {
let rooms_joined = services
.rooms
.state_cache
.rooms_joined(user_id)
.map(ToOwned::to_owned);
let rooms_invited = services
.rooms
.state_cache
.rooms_invited(user_id)
.map(|(r, _)| r);
let rooms_knocked = services
.rooms
.state_cache
.rooms_knocked(user_id)
.map(|(r, _)| r);
@@ -74,10 +71,7 @@ pub async fn leave_all_rooms(services: &Services, user_id: &UserId) {
warn!(%user_id, "Failed to leave {room_id} remotely: {e}");
}
services
.rooms
.state_cache
.forget(&room_id, user_id);
services.state_cache.forget(&room_id, user_id);
}
}
@@ -98,15 +92,14 @@ pub async fn leave_room(
blurhash: None,
};
let is_banned = services.rooms.metadata.is_banned(room_id);
let is_disabled = services.rooms.metadata.is_disabled(room_id);
let is_banned = services.metadata.is_banned(room_id);
let is_disabled = services.metadata.is_disabled(room_id);
pin_mut!(is_banned, is_disabled);
if is_banned.or(is_disabled).await {
// the room is banned/disabled, the room must be rejected locally since we
// cant/dont want to federate with this server
services
.rooms
.state_cache
.update_membership(
room_id,
@@ -123,13 +116,11 @@ pub async fn leave_room(
}
let dont_have_room = services
.rooms
.state_cache
.server_in_room(services.globals.server_name(), room_id)
.eq(&false);
let not_knocked = services
.rooms
.state_cache
.is_knocked(user_id, room_id)
.eq(&false);
@@ -145,27 +136,15 @@ pub async fn leave_room(
}
let last_state = services
.rooms
.state_cache
.invite_state(user_id, room_id)
.or_else(|_| {
services
.rooms
.state_cache
.knock_state(user_id, room_id)
})
.or_else(|_| {
services
.rooms
.state_cache
.left_state(user_id, room_id)
})
.or_else(|_| services.state_cache.knock_state(user_id, room_id))
.or_else(|_| services.state_cache.left_state(user_id, room_id))
.await
.ok();
// We always drop the invite, we can't rely on other servers
services
.rooms
.state_cache
.update_membership(
room_id,
@@ -178,10 +157,9 @@ pub async fn leave_room(
)
.await?;
} else {
let state_lock = services.rooms.state.mutex.lock(room_id).await;
let state_lock = services.state.mutex.lock(room_id).await;
let Ok(event) = services
.rooms
.state_accessor
.room_state_get_content::<RoomMemberEventContent>(
room_id,
@@ -195,7 +173,6 @@ pub async fn leave_room(
);
return services
.rooms
.state_cache
.update_membership(
room_id,
@@ -210,7 +187,6 @@ pub async fn leave_room(
};
services
.rooms
.timeline
.build_and_append_pdu(
PduBuilder::state(user_id.to_string(), &RoomMemberEventContent {
@@ -235,7 +211,6 @@ async fn remote_leave_room(services: &Services, user_id: &UserId, room_id: &Room
Err!(BadServerResponse("No remote server available to assist in leaving {room_id}."));
let mut servers: HashSet<OwnedServerName> = services
.rooms
.state_cache
.servers_invite_via(room_id)
.map(ToOwned::to_owned)
@@ -243,7 +218,6 @@ async fn remote_leave_room(services: &Services, user_id: &UserId, room_id: &Room
.await;
match services
.rooms
.state_cache
.invite_state(user_id, room_id)
.await
@@ -259,7 +233,6 @@ async fn remote_leave_room(services: &Services, user_id: &UserId, room_id: &Room
},
| _ => {
match services
.rooms
.state_cache
.knock_state(user_id, room_id)
.await

View File

@@ -25,7 +25,6 @@ pub(crate) async fn get_member_events_route(
body: Ruma<get_member_events::v3::Request>,
) -> Result<get_member_events::v3::Response> {
if !services
.rooms
.state_accessor
.user_can_see_state_events(body.sender_user(), &body.room_id)
.await
@@ -37,7 +36,6 @@ pub(crate) async fn get_member_events_route(
let not_membership = body.not_membership.as_ref();
Ok(get_member_events::v3::Response {
chunk: services
.rooms
.state_accessor
.room_state_full(&body.room_id)
.ready_filter_map(Result::ok)
@@ -62,7 +60,6 @@ pub(crate) async fn joined_members_route(
body: Ruma<joined_members::v3::Request>,
) -> Result<joined_members::v3::Response> {
if !services
.rooms
.state_accessor
.user_can_see_state_events(body.sender_user(), &body.room_id)
.await
@@ -72,7 +69,6 @@ pub(crate) async fn joined_members_route(
Ok(joined_members::v3::Response {
joined: services
.rooms
.state_accessor
.room_state_full(&body.room_id)
.ready_filter_map(Result::ok)

View File

@@ -42,7 +42,6 @@ pub(crate) async fn joined_rooms_route(
) -> Result<joined_rooms::v3::Response> {
Ok(joined_rooms::v3::Response {
joined_rooms: services
.rooms
.state_cache
.rooms_joined(body.sender_user())
.map(ToOwned::to_owned)
@@ -69,7 +68,7 @@ pub(crate) async fn banned_room_check(
}
if let Some(room_id) = room_id {
if services.rooms.metadata.is_banned(room_id).await
if services.metadata.is_banned(room_id).await
|| (room_id.server_name().is_some()
&& services
.config
@@ -105,7 +104,6 @@ pub(crate) async fn banned_room_check(
}
let all_joined_rooms: Vec<OwnedRoomId> = services
.rooms
.state_cache
.rooms_joined(user_id)
.map(Into::into)
@@ -150,7 +148,6 @@ pub(crate) async fn banned_room_check(
}
let all_joined_rooms: Vec<OwnedRoomId> = services
.rooms
.state_cache
.rooms_joined(user_id)
.map(Into::into)

View File

@@ -14,15 +14,9 @@ pub(crate) async fn unban_user_route(
State(services): State<crate::State>,
body: Ruma<unban_user::v3::Request>,
) -> Result<unban_user::v3::Response> {
let state_lock = services
.rooms
.state
.mutex
.lock(&body.room_id)
.await;
let state_lock = services.state.mutex.lock(&body.room_id).await;
let current_member_content = services
.rooms
.state_accessor
.get_member(&body.room_id, &body.user_id)
.await
@@ -36,7 +30,6 @@ pub(crate) async fn unban_user_route(
}
services
.rooms
.timeline
.build_and_append_pdu(
PduBuilder::state(body.user_id.to_string(), &RoomMemberEventContent {