use crate::{
err::*,
model::{Env, EnvId, User, UserId, Vm, VmEngine, VmId, VmTemplate},
};
use lazy_static::lazy_static;
use parking_lot::RwLock;
use ruc::{err::*, *};
use std::{
collections::{HashMap, HashSet},
ops::Deref,
sync::Arc,
};
lazy_static! {
pub static ref SERV: ServCtrl = Arc::new(Service::default());
pub static ref ENGINE: EngineCtrl = pnk!(EngineCtrl::init(None));
pub static ref TEMPLATE: TemplateCtrl = TemplateCtrl::default();
}
type ServCtrl = Arc<Service>;
#[derive(Default)]
pub struct Service {
#[allow(missing_docs)]
pub all_user: Arc<RwLock<HashMap<UserId, User>>>,
#[allow(missing_docs)]
pub all_env: Arc<RwLock<HashMap<EnvId, Env>>>,
#[allow(missing_docs)]
pub all_vm: Arc<RwLock<HashMap<VmId, Vm>>>,
}
#[derive(Clone)]
pub struct EngineCtrl(Arc<HashMap<String, Arc<dyn VmEngine>>>);
impl EngineCtrl {
pub fn init(em: Option<Vec<Arc<dyn VmEngine>>>) -> Option<EngineCtrl> {
static mut EM: Option<EngineCtrl> = None;
unsafe {
if let Some(e) = EM.as_ref() {
Some(e.clone())
} else if let Some(e) = em {
let ret = EngineCtrl(Arc::new(
e.into_iter().map(|ve| (ve.name().to_owned(), ve)).collect(),
));
EM = Some(ret.clone());
Some(ret)
} else {
None
}
}
}
}
impl Deref for EngineCtrl {
type Target = Arc<HashMap<String, Arc<dyn VmEngine>>>;
fn deref(&self) -> &Self::Target {
&self.0
}
}
#[derive(Default)]
pub struct TemplateCtrl(Arc<RwLock<HashMap<String, VmTemplate>>>);
impl TemplateCtrl {
#[inline(always)]
pub fn reinit(&mut self, t: HashMap<String, VmTemplate>) {
*self.0.write() = t;
}
#[inline(always)]
pub fn add(&mut self, t: HashMap<String, VmTemplate>) {
let mut ts = self.0.write();
t.into_iter().for_each(|(k, v)| {
ts.insert(k, v);
})
}
#[inline(always)]
pub fn add_safe(&mut self, t: HashMap<String, VmTemplate>) -> Result<()> {
if self.0.read().keys().any(|k| t.get(k).is_some()) {
return Err(e!(ERR_KK_CTRL_UPDATE_TEMPLATE).into());
}
self.add(t);
Ok(())
}
#[inline(always)]
pub fn del(&mut self, t: HashSet<String>) {
let mut ts = self.0.write();
t.iter().for_each(|t| {
ts.remove(t);
})
}
}
impl Deref for TemplateCtrl {
type Target = Arc<RwLock<HashMap<String, VmTemplate>>>;
fn deref(&self) -> &Self::Target {
&self.0
}
}