mirror of
https://gitlab.com/fabinfra/fabaccess/bffh.git
synced 2024-11-22 14:57:56 +01:00
Initiators first concept
This commit is contained in:
parent
fc1aea2f96
commit
5a4b03a16c
68
Cargo.lock
generated
68
Cargo.lock
generated
@ -424,6 +424,7 @@ dependencies = [
|
|||||||
"futures-signals",
|
"futures-signals",
|
||||||
"futures-test",
|
"futures-test",
|
||||||
"futures-util",
|
"futures-util",
|
||||||
|
"genawaiter",
|
||||||
"glob",
|
"glob",
|
||||||
"lazy_static",
|
"lazy_static",
|
||||||
"libc",
|
"libc",
|
||||||
@ -742,6 +743,36 @@ dependencies = [
|
|||||||
"slab",
|
"slab",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "genawaiter"
|
||||||
|
version = "0.99.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "c86bd0361bcbde39b13475e6e36cb24c329964aa2611be285289d1e4b751c1a0"
|
||||||
|
dependencies = [
|
||||||
|
"genawaiter-macro",
|
||||||
|
"genawaiter-proc-macro",
|
||||||
|
"proc-macro-hack",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "genawaiter-macro"
|
||||||
|
version = "0.99.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "0b32dfe1fdfc0bbde1f22a5da25355514b5e450c33a6af6770884c8750aedfbc"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "genawaiter-proc-macro"
|
||||||
|
version = "0.99.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "784f84eebc366e15251c4a8c3acee82a6a6f427949776ecb88377362a9621738"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro-error",
|
||||||
|
"proc-macro-hack",
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "getrandom"
|
name = "getrandom"
|
||||||
version = "0.1.15"
|
version = "0.1.15"
|
||||||
@ -1058,6 +1089,32 @@ dependencies = [
|
|||||||
"toml",
|
"toml",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "proc-macro-error"
|
||||||
|
version = "0.4.12"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "18f33027081eba0a6d8aba6d1b1c3a3be58cbb12106341c2d5759fcd9b5277e7"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro-error-attr",
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
"version_check",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "proc-macro-error-attr"
|
||||||
|
version = "0.4.12"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8a5b4b77fdb63c1eca72173d68d24501c54ab1269409f6b672c85deb18af69de"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
"syn-mid",
|
||||||
|
"version_check",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "proc-macro-hack"
|
name = "proc-macro-hack"
|
||||||
version = "0.5.19"
|
version = "0.5.19"
|
||||||
@ -1327,6 +1384,17 @@ dependencies = [
|
|||||||
"unicode-xid",
|
"unicode-xid",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "syn-mid"
|
||||||
|
version = "0.5.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "c42823f0ff906a3eb8109610e825221b07fb1456d45c7d01cf18cb581b23ecfb"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "take_mut"
|
name = "take_mut"
|
||||||
version = "0.2.2"
|
version = "0.2.2"
|
||||||
|
@ -62,6 +62,7 @@ rand = "0.7"
|
|||||||
|
|
||||||
async-channel = "1.5"
|
async-channel = "1.5"
|
||||||
easy-parallel = "3.1"
|
easy-parallel = "3.1"
|
||||||
|
genawaiter = "0.99"
|
||||||
|
|
||||||
[build-dependencies]
|
[build-dependencies]
|
||||||
capnpc = "0.13"
|
capnpc = "0.13"
|
||||||
|
@ -17,6 +17,12 @@ pub struct User {
|
|||||||
pub data: UserData,
|
pub data: UserData,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl User {
|
||||||
|
pub fn new(id: UserId, data: UserData) -> Self {
|
||||||
|
Self { id, data }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)]
|
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)]
|
||||||
/// Authorization Identity
|
/// Authorization Identity
|
||||||
///
|
///
|
||||||
@ -78,6 +84,16 @@ pub struct UserData {
|
|||||||
kv: HashMap<Box<[u8]>, Box<[u8]>>,
|
kv: HashMap<Box<[u8]>, Box<[u8]>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl UserData {
|
||||||
|
pub fn new(roles: Vec<RoleIdentifier>, priority: u64) -> Self {
|
||||||
|
Self {
|
||||||
|
roles: roles,
|
||||||
|
priority: priority,
|
||||||
|
kv: HashMap::new(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn is_zero(i: &u64) -> bool {
|
fn is_zero(i: &u64) -> bool {
|
||||||
*i == 0
|
*i == 0
|
||||||
}
|
}
|
||||||
|
@ -1,21 +1,87 @@
|
|||||||
|
use std::pin::Pin;
|
||||||
|
use std::task::{Poll, Context};
|
||||||
use std::future::Future;
|
use std::future::Future;
|
||||||
use smol::Task;
|
use smol::{Task, Timer};
|
||||||
|
|
||||||
use futures_signals::signal::Signal;
|
use futures::FutureExt;
|
||||||
use crate::machine::Machine;
|
use futures::future::BoxFuture;
|
||||||
|
|
||||||
|
use genawaiter::{sync::{Gen, GenBoxed, Co}, GeneratorState};
|
||||||
|
|
||||||
|
use futures_signals::signal::{Signal, MutableSignalCloned};
|
||||||
|
use crate::machine::{Machine, ReturnToken};
|
||||||
|
use crate::db::machine::MachineState;
|
||||||
|
use crate::db::user::{User, UserId, UserData};
|
||||||
|
|
||||||
use crate::error::Result;
|
use crate::error::Result;
|
||||||
|
|
||||||
pub struct Initiator {
|
pub struct Initiator<'a> {
|
||||||
machine: Box<dyn Signal<Item=Machine> + Send>,
|
signal: MutableSignalCloned<Option<Machine>>,
|
||||||
|
machine: Option<Machine>,
|
||||||
|
future: Option<BoxFuture<'a, (Option<User>, MachineState)>>,
|
||||||
|
token: Option<ReturnToken>,
|
||||||
|
step: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Initiator {
|
async fn producer(step: bool) -> (Option<User>, MachineState) {
|
||||||
pub fn run(self) -> impl Future<Output=()> {
|
Timer::after(std::time::Duration::from_secs(1)).await;
|
||||||
futures::future::pending()
|
if step {
|
||||||
|
return (None, MachineState::free());
|
||||||
|
} else {
|
||||||
|
let user = User::new(
|
||||||
|
UserId::new("test".to_string(), None, None),
|
||||||
|
UserData::new(vec![], 0),
|
||||||
|
);
|
||||||
|
let p = user.data.priority;
|
||||||
|
let id = user.id.clone();
|
||||||
|
return (Some(user), MachineState::used(id, p));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn load(config: &crate::config::Settings) -> Result<Vec<Initiator>> {
|
impl<'a> Initiator<'a> {
|
||||||
|
pub fn new(signal: MutableSignalCloned<Option<Machine>>) -> Self {
|
||||||
|
Self {
|
||||||
|
signal: signal,
|
||||||
|
machine: None,
|
||||||
|
future: None,
|
||||||
|
token: None,
|
||||||
|
step: false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> Future for Initiator<'a> {
|
||||||
|
type Output = ();
|
||||||
|
|
||||||
|
fn poll(mut self: Pin<&mut Self>, cx: &mut Context) -> Poll<Self::Output> {
|
||||||
|
let mut this = &mut *self;
|
||||||
|
|
||||||
|
// First of course, see what machine we should work with.
|
||||||
|
match Signal::poll_change(Pin::new(&mut this.signal), cx) {
|
||||||
|
Poll::Pending => { }
|
||||||
|
Poll::Ready(None) => return Poll::Ready(()),
|
||||||
|
// Keep in mind this is actually an Option<Machine>
|
||||||
|
Poll::Ready(Some(machine)) => this.machine = machine,
|
||||||
|
}
|
||||||
|
|
||||||
|
// Do as much work as we can:
|
||||||
|
loop {
|
||||||
|
// If there is a future, poll it
|
||||||
|
match this.future.as_mut().map(|future| Future::poll(Pin::new(future), cx)) {
|
||||||
|
None => {
|
||||||
|
this.future = Some(Box::pin(producer(this.step)));
|
||||||
|
this.step = !this.step;
|
||||||
|
},
|
||||||
|
Some(Poll::Ready((user, state))) => {
|
||||||
|
this.future.take();
|
||||||
|
this.machine.as_mut().map(|machine| machine.request_state_change(user.as_ref(), state));
|
||||||
|
}
|
||||||
|
Some(Poll::Pending) => return Poll::Pending,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn load<'a>() -> Result<Initiator<'a>> {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
@ -69,6 +69,13 @@ impl Machine {
|
|||||||
Self::construct(id, desc, MachineState::new())
|
Self::construct(id, desc, MachineState::new())
|
||||||
}).collect())
|
}).collect())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn request_state_change(&self, who: Option<&User>, new_state: MachineState)
|
||||||
|
-> Result<ReturnToken>
|
||||||
|
{
|
||||||
|
let mut guard = self.inner.try_lock().unwrap();
|
||||||
|
guard.request_state_change(who, new_state)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Deref for Machine {
|
impl Deref for Machine {
|
||||||
@ -131,10 +138,23 @@ impl Inner {
|
|||||||
/// along it or if the sending end gets dropped. Anybody who holds this token needs to check if
|
/// along it or if the sending end gets dropped. Anybody who holds this token needs to check if
|
||||||
/// the receiving end was canceled which indicates that the machine has been taken off their
|
/// the receiving end was canceled which indicates that the machine has been taken off their
|
||||||
/// hands.
|
/// hands.
|
||||||
pub async fn request_state_change(&mut self, who: &User, new_state: MachineState)
|
pub fn request_state_change(&mut self, who: Option<&User>, new_state: MachineState)
|
||||||
-> Result<ReturnToken>
|
-> Result<ReturnToken>
|
||||||
{
|
{
|
||||||
if self.state.lock_ref().is_higher_priority(who.data.priority) {
|
if who.is_none() {
|
||||||
|
if new_state.state == Status::Free {
|
||||||
|
return self.do_state_change(new_state);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if self.state.lock_ref().is_higher_priority(who.unwrap().data.priority) {
|
||||||
|
return self.do_state_change(new_state);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return Err(Error::Denied);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn do_state_change(&mut self, new_state: MachineState) -> Result<ReturnToken> {
|
||||||
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);
|
||||||
self.reset.replace(old_state);
|
self.reset.replace(old_state);
|
||||||
@ -144,9 +164,6 @@ impl Inner {
|
|||||||
return Ok(tx);
|
return Ok(tx);
|
||||||
}
|
}
|
||||||
|
|
||||||
return Err(Error::Denied);
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn set_state(&mut self, state: Status) {
|
pub fn set_state(&mut self, state: Status) {
|
||||||
self.state.set(MachineState { state })
|
self.state.set(MachineState { state })
|
||||||
}
|
}
|
||||||
@ -162,7 +179,7 @@ impl Inner {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
type ReturnToken = futures::channel::oneshot::Sender<()>;
|
pub type ReturnToken = futures::channel::oneshot::Sender<()>;
|
||||||
|
|
||||||
impl Future for Inner {
|
impl Future for Inner {
|
||||||
type Output = MachineState;
|
type Output = MachineState;
|
||||||
|
Loading…
Reference in New Issue
Block a user