mirror of
https://gitlab.com/fabinfra/fabaccess/bffh.git
synced 2024-11-10 17:43:23 +01:00
Make machine correctly load state and set previous/current use in API
This commit is contained in:
parent
9fcb7664aa
commit
47781b445e
@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "diflouroborane"
|
||||
version = "0.3.0"
|
||||
version = "0.3.1"
|
||||
authors = [ "dequbed <me@dequbed.space>"
|
||||
, "Kai Jan Kriegel <kai@kjkriegel.de>"
|
||||
, "Joseph Langosch <thejoklla@gmail.com>"
|
||||
|
@ -65,13 +65,52 @@ impl info::Server for Machine {
|
||||
_: info::GetMachineInfoExtendedParams,
|
||||
mut results: info::GetMachineInfoExtendedResults,
|
||||
) -> Promise<(), capnp::Error> {
|
||||
if self.perms.manage {
|
||||
let machine = self.machine.get_inner();
|
||||
let perms = self.perms.clone();
|
||||
let f = async move {
|
||||
if perms.manage {
|
||||
let mut builder = results.get();
|
||||
let mut extinfo = builder.init_machine_info_extended();
|
||||
let mut current = extinfo.init_current_user();
|
||||
current.set_username(&self.userid.uid);
|
||||
let guard = machine.lock().await;
|
||||
|
||||
// "previous" user
|
||||
if let Some(user) = guard.get_previous() {
|
||||
let mut previous = extinfo.reborrow().init_transfer_user();
|
||||
previous.set_username(&user.uid);
|
||||
}
|
||||
Promise::ok(())
|
||||
|
||||
let state = guard.read_state();
|
||||
let state_lock = state.lock_ref();
|
||||
match state_lock.state {
|
||||
Status::Free => {}
|
||||
Status::InUse(ref user) => if user.is_some() {
|
||||
let user = user.as_ref().unwrap();
|
||||
let mut current = extinfo.init_current_user();
|
||||
current.set_username(&user.uid);
|
||||
}
|
||||
Status::ToCheck(ref user) => {
|
||||
let mut current = extinfo.init_current_user();
|
||||
current.set_username(&user.uid);
|
||||
}
|
||||
Status::Blocked(ref user) => {
|
||||
let mut current = extinfo.init_current_user();
|
||||
current.set_username(&user.uid);
|
||||
}
|
||||
Status::Disabled => {}
|
||||
Status::Reserved(ref user) => {
|
||||
let mut current = extinfo.init_current_user();
|
||||
current.set_username(&user.uid);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
};
|
||||
|
||||
let g = smol::future::race(f, smol::Timer::after(Duration::from_secs(4))
|
||||
.map(|_| Err(capnp::Error::failed("Waiting for machine lock timed out!".to_string()))));
|
||||
|
||||
Promise::from_future(g)
|
||||
}
|
||||
|
||||
fn get_reservation_list(
|
||||
|
@ -24,10 +24,12 @@ pub mod access;
|
||||
/// Stores&Retrieves Machines
|
||||
pub mod machine;
|
||||
|
||||
pub type MachineDB = machine::internal::Internal;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct Databases {
|
||||
pub access: Arc<access::AccessControl>,
|
||||
pub machine: Arc<machine::internal::Internal>,
|
||||
pub machine: Arc<MachineDB>,
|
||||
pub userdb: Arc<user::Internal>,
|
||||
}
|
||||
|
||||
|
@ -75,7 +75,7 @@ impl MachineState {
|
||||
|
||||
pub fn init(log: Logger, _config: &Config, env: Arc<lmdb::Environment>) -> Result<Internal> {
|
||||
let mut flags = lmdb::DatabaseFlags::empty();
|
||||
flags.set(lmdb::DatabaseFlags::INTEGER_KEY, true);
|
||||
//flags.set(lmdb::DatabaseFlags::INTEGER_KEY, true);
|
||||
let machdb = env.create_db(Some("machines"), flags)?;
|
||||
debug!(&log, "Opened machine db successfully.");
|
||||
|
||||
|
@ -2,7 +2,7 @@ use std::sync::Arc;
|
||||
|
||||
use slog::Logger;
|
||||
|
||||
use lmdb::{Environment, Transaction, RwTransaction, Cursor};
|
||||
use lmdb::{Environment, Transaction, RwTransaction, Cursor, RoTransaction};
|
||||
|
||||
use super::{MachineIdentifier, MachineState};
|
||||
use crate::error::Result;
|
||||
@ -37,11 +37,11 @@ impl Internal {
|
||||
self.get_with_txn(&txn, id)
|
||||
}
|
||||
|
||||
pub fn put_with_txn(&self, txn: &mut RwTransaction, uuid: &String, status: &MachineState)
|
||||
pub fn put_with_txn(&self, txn: &mut RwTransaction, id: &String, status: &MachineState)
|
||||
-> Result<()>
|
||||
{
|
||||
let bytes = flexbuffers::to_vec(status)?;
|
||||
txn.put(self.db, &uuid.as_bytes(), &bytes, lmdb::WriteFlags::empty())?;
|
||||
txn.put(self.db, &id.as_bytes(), &bytes, lmdb::WriteFlags::empty())?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
@ -52,11 +52,20 @@ impl Internal {
|
||||
txn.commit().map_err(Into::into)
|
||||
}
|
||||
|
||||
pub fn iter<T: Transaction>(&self, txn: &T) -> Result<impl Iterator<Item=MachineState>> {
|
||||
pub fn iter<'txn, T: Transaction>(&self, txn: &'txn T)
|
||||
-> Result<impl Iterator<Item=(&'txn str, MachineState)>>
|
||||
{
|
||||
let mut cursor = txn.open_ro_cursor(self.db)?;
|
||||
Ok(cursor.iter_start().map(|buf| {
|
||||
let (_kbuf, vbuf) = buf.unwrap();
|
||||
flexbuffers::from_slice(vbuf).unwrap()
|
||||
let (kbuf, vbuf) = buf.unwrap();
|
||||
let id = unsafe { std::str::from_utf8_unchecked(kbuf) };
|
||||
let state = flexbuffers::from_slice(vbuf).unwrap();
|
||||
(id, state)
|
||||
}))
|
||||
}
|
||||
|
||||
pub fn txn(&self) -> Result<RoTransaction> {
|
||||
let txn = self.env.begin_ro_txn()?;
|
||||
Ok(txn)
|
||||
}
|
||||
}
|
||||
|
@ -19,12 +19,13 @@ use futures::channel::{mpsc, oneshot};
|
||||
use futures_signals::signal::Signal;
|
||||
use futures_signals::signal::SignalExt;
|
||||
use futures_signals::signal::{Mutable, ReadOnlyMutable};
|
||||
use slog::Logger;
|
||||
|
||||
use crate::error::{Result, Error};
|
||||
|
||||
use crate::db::access;
|
||||
use crate::db::{access, Databases, MachineDB};
|
||||
use crate::db::machine::{MachineIdentifier, MachineState, Status};
|
||||
use crate::db::user::{User, UserData};
|
||||
use crate::db::user::{User, UserData, UserId};
|
||||
|
||||
use crate::network::MachineMap;
|
||||
use crate::space;
|
||||
@ -73,13 +74,14 @@ impl Machine {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn construct
|
||||
( id: MachineIdentifier
|
||||
, desc: MachineDescription
|
||||
, state: MachineState
|
||||
pub fn construct(
|
||||
id: MachineIdentifier,
|
||||
desc: MachineDescription,
|
||||
state: MachineState,
|
||||
db: Arc<MachineDB>,
|
||||
) -> Machine
|
||||
{
|
||||
Self::new(Inner::new(id, state), desc)
|
||||
Self::new(Inner::new(id, state, db), desc)
|
||||
}
|
||||
|
||||
pub fn do_state_change(&self, new_state: MachineState)
|
||||
@ -136,17 +138,20 @@ pub struct Inner {
|
||||
/// case of an actor it should then make sure that the real world matches up with the set state
|
||||
state: Mutable<MachineState>,
|
||||
reset: Option<MachineState>,
|
||||
|
||||
previous: Option<UserId>,
|
||||
|
||||
db: Arc<MachineDB>,
|
||||
}
|
||||
|
||||
impl Inner {
|
||||
pub fn new ( id: MachineIdentifier
|
||||
, state: MachineState
|
||||
) -> Inner
|
||||
{
|
||||
pub fn new(id: MachineIdentifier, state: MachineState, db: Arc<MachineDB>) -> Inner {
|
||||
Inner {
|
||||
id,
|
||||
state: Mutable::new(state),
|
||||
reset: None,
|
||||
previous: None,
|
||||
db,
|
||||
}
|
||||
}
|
||||
|
||||
@ -162,8 +167,13 @@ impl Inner {
|
||||
Box::pin(self.state.signal_cloned().dedupe_cloned())
|
||||
}
|
||||
|
||||
fn replace_state(&mut self, new_state: MachineState) -> MachineState {
|
||||
self.db.put(&self.id, &new_state);
|
||||
self.state.replace(new_state)
|
||||
}
|
||||
|
||||
pub fn do_state_change(&mut self, new_state: MachineState) {
|
||||
let old_state = self.state.replace(new_state);
|
||||
let old_state = self.replace_state(new_state);
|
||||
self.reset.replace(old_state);
|
||||
}
|
||||
|
||||
@ -176,9 +186,30 @@ impl Inner {
|
||||
}
|
||||
|
||||
pub fn reset_state(&mut self) {
|
||||
if let Some(state) = self.reset.take() {
|
||||
self.state.replace(state);
|
||||
let previous_state = self.read_state();
|
||||
let state_lock = previous_state.lock_ref();
|
||||
// Only update previous user if state changed from InUse or ToCheck to whatever.
|
||||
match state_lock.state {
|
||||
Status::InUse(ref user) => {
|
||||
self.previous = user.clone();
|
||||
},
|
||||
Status::ToCheck(ref user) => {
|
||||
self.previous = Some(user.clone());
|
||||
},
|
||||
_ => {},
|
||||
}
|
||||
drop(state_lock);
|
||||
|
||||
if let Some(state) = self.reset.take() {
|
||||
self.replace_state(state);
|
||||
} else {
|
||||
// Default to Free
|
||||
self.replace_state(MachineState::free());
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_previous(&self) -> &Option<UserId> {
|
||||
&self.previous
|
||||
}
|
||||
}
|
||||
|
||||
@ -242,15 +273,22 @@ impl MachineDescription {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn load(config: &crate::config::Config)
|
||||
pub fn load(config: &crate::config::Config, db: Databases, log: &Logger)
|
||||
-> Result<MachineMap>
|
||||
{
|
||||
let mut map = config.machines.clone();
|
||||
let db = db.machine;
|
||||
|
||||
let it = map.drain()
|
||||
.map(|(k,v)| {
|
||||
// TODO: Read state from the state db
|
||||
(v.name.clone(), Machine::construct(k, v, MachineState::new()))
|
||||
if let Some(state) = db.get(&k).unwrap() {
|
||||
debug!(log, "Loading old state from db for {}: {:?}", &k, &state);
|
||||
(v.name.clone(), Machine::construct(k, v, state, db.clone()))
|
||||
} else {
|
||||
debug!(log, "No old state found in db for {}, creating new.", &k);
|
||||
(v.name.clone(), Machine::construct(k, v, MachineState::new(), db.clone()))
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
|
11
src/main.rs
11
src/main.rs
@ -167,7 +167,16 @@ fn maybe(matches: clap::ArgMatches, log: Arc<Logger>) -> Result<(), Error> {
|
||||
let ex = Executor::new();
|
||||
let db = db::Databases::new(&log, &config)?;
|
||||
|
||||
let machines = machine::load(&config)?;
|
||||
{
|
||||
info!(log, "Loaded DB state:");
|
||||
let txn = db.machine.txn()?;
|
||||
for (id, state) in db.machine.iter(&txn)? {
|
||||
info!(log, "- {}: {:?}", id, state);
|
||||
}
|
||||
info!(log, "Loaded DB state END.");
|
||||
}
|
||||
|
||||
let machines = machine::load(&config, db.clone(), &log)?;
|
||||
let (actor_map, actors) = actor::load(&log, &config)?;
|
||||
let (init_map, initiators) = initiator::load(&log, &config)?;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user