grapevine/src/service.rs
2024-11-01 14:25:52 -07:00

193 lines
6.6 KiB
Rust

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<admin::Service>,
pub(crate) globals: globals::Service,
pub(crate) key_backups: key_backups::Service,
pub(crate) media: media::Service,
pub(crate) sending: Arc<sending::Service>,
}
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<FilterReloadHandles>,
) -> Result<Self> {
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"
);
}
}