Machines refactor #2

This commit is contained in:
Gregor Reitzenstein 2020-12-01 08:39:34 +01:00
parent 737b05c012
commit 8c1fbfd1a9
6 changed files with 27 additions and 73 deletions

View File

@ -8,7 +8,6 @@ use crate::connection::Session;
use crate::db::Databases; use crate::db::Databases;
use crate::db::machine::uuid_from_api; use crate::db::machine::uuid_from_api;
use crate::db::machine::MachineDB;
use super::machine::Machine; use super::machine::Machine;

View File

@ -26,7 +26,7 @@ pub mod machine;
#[derive(Clone)] #[derive(Clone)]
pub struct Databases { pub struct Databases {
pub access: Arc<access::AccessControl>, pub access: Arc<access::AccessControl>,
pub machine: Arc<machine::MachineDB>, pub machine: Arc<machine::internal::Internal>,
pub passdb: Arc<pass::PassDB>, pub passdb: Arc<pass::PassDB>,
} }
@ -50,7 +50,6 @@ impl Databases {
// Error out if any of the subsystems failed to start. // Error out if any of the subsystems failed to start.
let defs = crate::machine::MachineDescription::load_file(&config.machines)?; let defs = crate::machine::MachineDescription::load_file(&config.machines)?;
let machdb = machine::MachineDB::new(mdb, defs);
let mut ac = access::AccessControl::new(); let mut ac = access::AccessControl::new();
@ -62,8 +61,8 @@ impl Databases {
Ok(Self { Ok(Self {
access: Arc::new(ac), access: Arc::new(ac),
machine: Arc::new(machdb),
passdb: Arc::new(passdb), passdb: Arc::new(passdb),
machine: Arc::new(mdb)
}) })
} }
} }

View File

@ -36,7 +36,7 @@ use crate::db::user::UserId;
pub mod internal; pub mod internal;
use internal::Internal; use internal::Internal;
pub type MachineIdentifier = Uuid; pub type MachineIdentifier = String;
pub type Priority = u64; pub type Priority = u64;
/// Status of a Machine /// Status of a Machine
@ -77,6 +77,10 @@ pub struct MachineState {
} }
impl MachineState { impl MachineState {
pub fn new() -> Self {
Self { state: Status::Free }
}
/// Check if the given priority is higher than one's own. /// Check if the given priority is higher than one's own.
/// ///
/// If `self` does not have a priority then this function always returns `true` /// If `self` does not have a priority then this function always returns `true`
@ -103,47 +107,3 @@ pub fn init(log: Logger, config: &Settings, env: Arc<lmdb::Environment>) -> Resu
Ok(Internal::new(log, env, machdb)) Ok(Internal::new(log, env, machdb))
} }
type MachMap = HashMap<MachineIdentifier, MachineDescription>;
#[derive(Debug)]
pub struct MachineDB {
state_db: Internal,
def_db: MachMap,
signals_db: HashMap<MachineIdentifier, Mutable<MachineState>>,
}
impl MachineDB {
pub fn new(state_db: Internal, def_db: MachMap) -> Self {
Self {
state_db: state_db,
def_db: def_db,
signals_db: HashMap::new(),
}
}
pub fn exists(&self, id: MachineIdentifier) -> bool {
self.def_db.get(&id).is_some()
}
pub fn get_desc(&self, id: &MachineIdentifier) -> Option<&MachineDescription> {
self.def_db.get(&id)
}
pub fn get_state(&self, id: &MachineIdentifier) -> Option<MachineState> {
// TODO: Error Handling
self.state_db.get(id).unwrap_or(None)
}
pub fn update_state(&self, id: &MachineIdentifier, new_state: MachineState) -> Result<()> {
// If an error happens the new state was not applied so this will not desync the sources
self.state_db.put(id, &new_state)?;
self.signals_db.get(id).map(|mutable| mutable.set(new_state));
Ok(())
}
pub fn get_signal(&self, id: &MachineIdentifier) -> Option<MutableSignalCloned<MachineState>> {
self.signals_db.get(&id).map(|mutable| mutable.signal_cloned())
}
}

View File

@ -57,11 +57,17 @@ impl Machine {
pub fn construct pub fn construct
( id: MachineIdentifier ( id: MachineIdentifier
, desc: MachineDescription , desc: MachineDescription
, access: access::AccessControl
, state: MachineState , state: MachineState
) -> Machine ) -> Machine
{ {
Self::new(Inner::new(id, desc, access, state)) Self::new(Inner::new(id, desc, state))
}
pub fn from_file<P: AsRef<Path>>(path: P) -> Result<Vec<Machine>> {
let map: HashMap<MachineIdentifier, MachineDescription> = MachineDescription::load_file(path)?;
map.drain().map(|(id, desc)| {
Self::construct(id, desc, MachineState::new())
}).collect()
} }
} }
@ -93,19 +99,16 @@ pub struct Inner {
state: Mutable<MachineState>, state: Mutable<MachineState>,
reset: Option<MachineState>, reset: Option<MachineState>,
rx: Option<futures::channel::oneshot::Receiver<()>>, rx: Option<futures::channel::oneshot::Receiver<()>>,
access: access::AccessControl,
} }
impl Inner { impl Inner {
pub fn new(id: MachineIdentifier, desc: MachineDescription, access: access::AccessControl, state: MachineState) -> Inner { pub fn new(id: MachineIdentifier, desc: MachineDescription, state: MachineState) -> Inner {
Inner { Inner {
id: id, id: id,
desc: desc, desc: desc,
state: Mutable::new(state), state: Mutable::new(state),
reset: None, reset: None,
rx: None, rx: None,
access: access,
} }
} }
@ -131,7 +134,6 @@ impl Inner {
pub async fn request_state_change(&mut self, who: &User, new_state: MachineState) pub async fn request_state_change(&mut self, who: &User, new_state: MachineState)
-> Result<ReturnToken> -> Result<ReturnToken>
{ {
if self.access.check(&who.data, &self.desc.privs.write).await? {
if self.state.lock_ref().is_higher_priority(who.data.priority) { if self.state.lock_ref().is_higher_priority(who.data.priority) {
let (tx, rx) = futures::channel::oneshot::channel(); let (tx, rx) = futures::channel::oneshot::channel();
let old_state = self.state.replace(new_state); let old_state = self.state.replace(new_state);
@ -141,7 +143,6 @@ impl Inner {
self.rx.replace(rx); self.rx.replace(rx);
return Ok(tx); return Ok(tx);
} }
}
return Err(Error::Denied); return Err(Error::Denied);
} }

View File

@ -1,7 +1,5 @@
use std::sync::Arc; use std::sync::Arc;
use crate::db::machine::MachineDB;
mod actuators; mod actuators;
mod sensors; mod sensors;
@ -18,10 +16,10 @@ pub struct Registries {
} }
impl Registries { impl Registries {
pub fn new(db: Arc<MachineDB>) -> Self { pub fn new() -> Self {
Registries { Registries {
actuators: actuators::Actuators::new(), actuators: actuators::Actuators::new(),
sensors: sensors::Sensors::new(db), sensors: sensors::Sensors::new(),
} }
} }
} }

View File

@ -4,7 +4,6 @@ use futures::{Future, Stream};
use futures::future::BoxFuture; use futures::future::BoxFuture;
use futures_signals::signal::Signal; use futures_signals::signal::Signal;
use crate::db::user::UserId; use crate::db::user::UserId;
use crate::db::machine::MachineDB;
use std::sync::Arc; use std::sync::Arc;
use smol::lock::RwLock; use smol::lock::RwLock;
@ -13,14 +12,12 @@ use std::collections::HashMap;
#[derive(Clone)] #[derive(Clone)]
pub struct Sensors { pub struct Sensors {
inner: Arc<RwLock<Inner>>, inner: Arc<RwLock<Inner>>,
db: Arc<MachineDB>,
} }
impl Sensors { impl Sensors {
pub fn new(db: Arc<MachineDB>) -> Self { pub fn new() -> Self {
Sensors { Sensors {
inner: Arc::new(RwLock::new(Inner::new())), inner: Arc::new(RwLock::new(Inner::new())),
db: db,
} }
} }
} }