You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

100 lines
2.4 KiB
Rust

use sysf::registry::{DependencyTree, Registry};
use sysf::unit::UnitState;
use std::collections::HashMap;
use sysf::config::loader::Loader;
use sysf::utils::asyn::AsyncQueue;
use async_std::prelude::StreamExt;
use async_std::task;
use crate::manager::ManagerSignal::*;
use async_std::sync::{Arc, Mutex, MutexGuard};
#[derive(Clone, Debug)]
pub enum ManagerSignal {
TargetUpdate(String),
Noop,
}
impl Default for ManagerSignal {
fn default() -> Self {
Noop
}
}
#[derive(Clone, Default, Debug)]
pub struct Manager {
state: Arc<Mutex<ManagerState>>,
queue: AsyncQueue<ManagerSignal>,
}
#[derive(Clone, Default, Debug)]
pub struct ManagerState {
dependency_tree: DependencyTree,
unit_status: HashMap<String, UnitState>,
registry: Registry,
queue: AsyncQueue<ManagerSignal>,
}
impl Manager {
pub fn new(loader: Loader) -> Manager {
let queue = AsyncQueue::new();
Manager {
state: Arc::new(Mutex::new(ManagerState {
dependency_tree: DependencyTree::default(),
unit_status: HashMap::new(),
registry: Registry::with_loader(loader),
queue: queue.clone(),
})),
queue,
}
}
pub async fn with<F>(&mut self, block: F)
where F: FnOnce(MutexGuard<ManagerState>)
{
block(self.state.lock().await)
}
pub fn target(&mut self, target: &str) {
self.queue.push(ManagerSignal::TargetUpdate(target.to_string()));
}
pub fn signal(&mut self, signal: ManagerSignal) {
self.queue.push(signal);
}
pub async fn run(&mut self) {
while let Some(signal) = self.queue.next().await {
let mut copy: Manager = self.clone();
task::spawn(async {
match signal {
TargetUpdate(target) => {
copy.update_target(target).await;
}
_ => {}
}
});
}
}
pub fn get_remote(&self) -> ManagerRemote {
ManagerRemote(self.queue.clone())
}
async fn update_target(mut self, target: String) {
let mut me = self.state.lock().await;
let tree = me.registry.get_dependency_tree(&target).await;
me.dependency_tree = tree;
}
}
pub struct ManagerRemote(AsyncQueue<ManagerSignal>);
impl ManagerRemote {
pub fn signal(&mut self, signal: ManagerSignal) {
self.0.push(signal);
}
}