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::machine::uuid_from_api;
use crate::db::machine::MachineDB;
use super::machine::Machine;

View File

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

View File

@ -36,7 +36,7 @@ use crate::db::user::UserId;
pub mod internal;
use internal::Internal;
pub type MachineIdentifier = Uuid;
pub type MachineIdentifier = String;
pub type Priority = u64;
/// Status of a Machine
@ -77,6 +77,10 @@ pub struct MachineState {
}
impl MachineState {
pub fn new() -> Self {
Self { state: Status::Free }
}
/// Check if the given priority is higher than one's own.
///
/// 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))
}
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
( id: MachineIdentifier
, desc: MachineDescription
, access: access::AccessControl
, state: MachineState
) -> 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>,
reset: Option<MachineState>,
rx: Option<futures::channel::oneshot::Receiver<()>>,
access: access::AccessControl,
}
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 {
id: id,
desc: desc,
state: Mutable::new(state),
reset: None,
rx: None,
access: access,
}
}
@ -131,16 +134,14 @@ impl Inner {
pub async fn request_state_change(&mut self, who: &User, new_state: MachineState)
-> Result<ReturnToken>
{
if self.access.check(&who.data, &self.desc.privs.write).await? {
if self.state.lock_ref().is_higher_priority(who.data.priority) {
let (tx, rx) = futures::channel::oneshot::channel();
let old_state = self.state.replace(new_state);
self.reset.replace(old_state);
// Also this drops the old receiver, which will signal to the initiator that the
// machine has been taken off their hands.
self.rx.replace(rx);
return Ok(tx);
}
if self.state.lock_ref().is_higher_priority(who.data.priority) {
let (tx, rx) = futures::channel::oneshot::channel();
let old_state = self.state.replace(new_state);
self.reset.replace(old_state);
// Also this drops the old receiver, which will signal to the initiator that the
// machine has been taken off their hands.
self.rx.replace(rx);
return Ok(tx);
}
return Err(Error::Denied);

View File

@ -1,7 +1,5 @@
use std::sync::Arc;
use crate::db::machine::MachineDB;
mod actuators;
mod sensors;
@ -18,10 +16,10 @@ pub struct Registries {
}
impl Registries {
pub fn new(db: Arc<MachineDB>) -> Self {
pub fn new() -> Self {
Registries {
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_signals::signal::Signal;
use crate::db::user::UserId;
use crate::db::machine::MachineDB;
use std::sync::Arc;
use smol::lock::RwLock;
@ -13,14 +12,12 @@ use std::collections::HashMap;
#[derive(Clone)]
pub struct Sensors {
inner: Arc<RwLock<Inner>>,
db: Arc<MachineDB>,
}
impl Sensors {
pub fn new(db: Arc<MachineDB>) -> Self {
pub fn new() -> Self {
Sensors {
inner: Arc::new(RwLock::new(Inner::new())),
db: db,
}
}
}