diff --git a/src/service/manager.rs b/src/service/manager.rs index af59b4a4..447cd6fe 100644 --- a/src/service/manager.rs +++ b/src/service/manager.rs @@ -54,7 +54,7 @@ impl Manager { ); debug!("Starting service workers..."); - for service in self.services.service.values() { + for (service, ..) in self.services.service.values() { self.start_worker(&mut workers, service).await?; } diff --git a/src/service/service.rs b/src/service/service.rs index 3b8f4231..ab41753a 100644 --- a/src/service/service.rs +++ b/src/service/service.rs @@ -1,11 +1,11 @@ -use std::{collections::BTreeMap, fmt::Write, sync::Arc}; +use std::{any::Any, collections::BTreeMap, fmt::Write, sync::Arc}; use async_trait::async_trait; use conduit::{utils::string::split_once_infallible, Result, Server}; use database::Database; #[async_trait] -pub(crate) trait Service: Send + Sync { +pub(crate) trait Service: Any + Send + Sync { /// Implement the construction of the service instance. Services are /// generally singletons so expect this to only be called once for a /// service type. Note that it may be called again after a server reload, @@ -40,7 +40,16 @@ pub(crate) struct Args<'a> { pub(crate) _service: &'a Map, } -pub(crate) type Map = BTreeMap>; +pub(crate) type Map = BTreeMap; +pub(crate) type MapVal = (Arc, Arc); + +pub(crate) fn get(map: &Map, name: &str) -> Option> { + map.get(name).map(|(_, s)| { + s.clone() + .downcast::() + .expect("Service must be correctly downcast.") + }) +} #[inline] pub(crate) fn make_name(module_path: &str) -> &str { split_once_infallible(module_path, "::").1 } diff --git a/src/service/services.rs b/src/service/services.rs index cc9ec290..0aac10dc 100644 --- a/src/service/services.rs +++ b/src/service/services.rs @@ -1,4 +1,4 @@ -use std::{collections::BTreeMap, fmt::Write, sync::Arc}; +use std::{any::Any, collections::BTreeMap, fmt::Write, sync::Arc}; use conduit::{debug, debug_info, info, trace, Result, Server}; use database::Database; @@ -7,7 +7,7 @@ use tokio::sync::Mutex; use crate::{ account_data, admin, appservice, globals, key_backups, manager::Manager, - media, presence, pusher, rooms, sending, + media, presence, pusher, rooms, sending, service, service::{Args, Map, Service}, transaction_ids, uiaa, updates, users, }; @@ -44,7 +44,7 @@ impl Services { db: &db, _service: &service, })?; - service.insert(built.name().to_owned(), built.clone()); + service.insert(built.name().to_owned(), (built.clone(), built.clone())); built }}; } @@ -128,7 +128,7 @@ impl Services { } pub async fn clear_cache(&self) { - for service in self.service.values() { + for (service, ..) in self.service.values() { service.clear_cache(); } @@ -143,7 +143,7 @@ impl Services { pub async fn memory_usage(&self) -> Result { let mut out = String::new(); - for service in self.service.values() { + for (service, ..) in self.service.values() { service.memory_usage(&mut out)?; } @@ -163,9 +163,11 @@ impl Services { fn interrupt(&self) { debug!("Interrupting services..."); - for (name, service) in &self.service { + for (name, (service, ..)) in &self.service { trace!("Interrupting {name}"); service.interrupt(); } } + + pub fn get(&self, name: &str) -> Option> { service::get::(&self.service, name) } }