use std::sync::{Arc, OnceLock}; use crate::{observability::FilterReloadHandles, Config, Result}; pub(crate) mod account_data; pub(crate) mod admin; pub(crate) mod appservice; pub(crate) mod globals; pub(crate) mod key_backups; pub(crate) mod media; pub(crate) mod pdu; pub(crate) mod pusher; pub(crate) mod rooms; pub(crate) mod sending; pub(crate) mod transaction_ids; pub(crate) mod uiaa; pub(crate) mod users; static SERVICES: OnceLock<&'static Services> = OnceLock::new(); /// Convenient access to the global [`Services`] instance pub(crate) fn services() -> &'static Services { SERVICES.get().expect("`Services::install` should have been called first") } pub(crate) struct Services { pub(crate) appservice: appservice::Service, pub(crate) pusher: pusher::Service, pub(crate) rooms: rooms::Service, pub(crate) transaction_ids: transaction_ids::Service, pub(crate) uiaa: uiaa::Service, pub(crate) users: users::Service, pub(crate) account_data: account_data::Service, pub(crate) admin: Arc, pub(crate) globals: globals::Service, pub(crate) key_backups: key_backups::Service, pub(crate) media: media::Service, pub(crate) sending: Arc, } impl Services { #[allow(clippy::too_many_lines)] pub(crate) fn build< D: appservice::Data + pusher::Data + rooms::Data + transaction_ids::Data + uiaa::Data + users::Data + account_data::Data + globals::Data + key_backups::Data + media::Data + sending::Data + 'static, >( db: &'static D, config: Config, reload_handles: Option, ) -> Result { Ok(Self { appservice: appservice::Service::new(db)?, pusher: pusher::Service { db, }, rooms: rooms::Service { alias: rooms::alias::Service::new(db), auth_chain: rooms::auth_chain::Service::new( db, #[allow( clippy::as_conversions, clippy::cast_sign_loss, clippy::cast_possible_truncation )] { (100_000.0 * config.cache_capacity_modifier) as usize }, ), directory: db, edus: rooms::edus::Service { read_receipt: db, typing: rooms::edus::typing::Service::new(), }, event_handler: rooms::event_handler::Service, lazy_loading: rooms::lazy_loading::Service::new(db), metadata: db, outlier: db, pdu_metadata: rooms::pdu_metadata::Service { db, }, search: db, short: rooms::short::Service::new( db, #[allow( clippy::as_conversions, clippy::cast_sign_loss, clippy::cast_possible_truncation )] { (100_000.0 * config.cache_capacity_modifier) as usize }, #[allow( clippy::as_conversions, clippy::cast_sign_loss, clippy::cast_possible_truncation )] { (100_000.0 * config.cache_capacity_modifier) as usize }, #[allow( clippy::as_conversions, clippy::cast_sign_loss, clippy::cast_possible_truncation )] { (100_000.0 * config.cache_capacity_modifier) as usize }, #[allow( clippy::as_conversions, clippy::cast_sign_loss, clippy::cast_possible_truncation )] { (100_000.0 * config.cache_capacity_modifier) as usize }, ), state: rooms::state::Service { db, }, state_accessor: rooms::state_accessor::Service::new( db, #[allow( clippy::as_conversions, clippy::cast_sign_loss, clippy::cast_possible_truncation )] { (100.0 * config.cache_capacity_modifier) as usize }, #[allow( clippy::as_conversions, clippy::cast_sign_loss, clippy::cast_possible_truncation )] { (100.0 * config.cache_capacity_modifier) as usize }, ), state_cache: rooms::state_cache::Service::new(db), state_compressor: rooms::state_compressor::Service::new( db, #[allow( clippy::as_conversions, clippy::cast_sign_loss, clippy::cast_possible_truncation )] { (100.0 * config.cache_capacity_modifier) as usize }, ), timeline: rooms::timeline::Service::new( db, config.pdu_cache_capacity, ), threads: rooms::threads::Service { db, }, spaces: rooms::spaces::Service::new(200), user: db, }, transaction_ids: db, uiaa: uiaa::Service::new(db), users: users::Service::new(db), account_data: db, admin: admin::Service::build(), key_backups: db, media: media::Service { db, }, sending: sending::Service::build(db, &config), globals: globals::Service::load(db, config, reload_handles)?, }) } /// Installs `self` to be globally accessed via [`services`] pub(crate) fn install(self) { assert!( SERVICES.set(Box::leak(Box::new(self))).is_ok(), "Services::install was called more than once" ); } }