webterm_agent/models/
frontend_registry.rs1use crate::models::agent_error::AgentError;
2use crate::models::frontend::Frontend;
3use std::collections::HashMap;
4use std::sync::{Arc, OnceLock};
5use tokio::sync::{Mutex, RwLock};
6use tracing::debug;
7use webterm_core::types::FrontendId;
8
9pub struct FrontendRegistry {
14 map: RwLock<HashMap<FrontendId, Arc<Mutex<Frontend>>>>,
15}
16
17impl FrontendRegistry {
18 pub(crate) async fn singleton() -> &'static Self {
19 static INSTANCE: OnceLock<FrontendRegistry> = OnceLock::new();
20 INSTANCE.get_or_init(|| Self {
21 map: RwLock::new(HashMap::new()),
22 })
23 }
24
25 pub async fn find(frontend_id: FrontendId) -> Result<Arc<Mutex<Frontend>>, AgentError> {
26 let registry = Self::singleton().await;
27 registry
28 .map
29 .read()
30 .await
31 .get(&frontend_id)
32 .ok_or(AgentError::FrontendNotFound(Some(frontend_id)))
33 .cloned()
34 }
35
36 pub async fn build_frontend(
37 frontend_id: FrontendId,
38 ) -> Result<Arc<Mutex<Frontend>>, AgentError> {
39 let registry = Self::singleton().await;
40 debug!("Registering frontend {:?}", frontend_id);
41 let frontend = Arc::new(Mutex::new(Frontend::new(frontend_id)));
42 registry
43 .map
44 .write()
45 .await
46 .insert(frontend_id, frontend.clone());
47
48 Ok(frontend)
49 }
50}