tag2upload_service_manager/
o2m_tracker.rs
use crate::prelude::*;
use std::sync::{Mutex, MutexGuard};
#[derive(Debug, Default)]
pub struct WorkerTracker {
state: Mutex<State>,
}
#[derive(Debug, Default)]
struct State {
entries: Slab<WorkerReport>,
}
#[derive(Debug, Clone, Ord, PartialOrd, Eq, PartialEq, Deftly)]
#[derive_deftly(UiMap)]
pub struct WorkerReport {
pub ident: String,
pub last_contact: TimeT,
pub phase: WorkerPhase,
pub source: NoneIsEmpty<PackageName>,
pub version: NoneIsEmpty<VersionString>,
pub status: Option<JobStatus>,
pub info: Option<String>,
}
#[derive(Debug, Clone, Ord, PartialOrd, Eq, PartialEq, Deftly)]
#[derive_deftly(UiDisplayEnum)]
pub enum WorkerPhase {
Init,
Idle,
Selected,
Building,
}
#[derive(Debug)]
pub struct TrackedWorker {
tracker: Arc<WorkerTracker>,
lid: usize,
}
impl WorkerTracker {
pub fn new_worker(
self: Arc<Self>,
initial: WorkerReport,
) -> TrackedWorker {
let mut state = self.lock();
let lid = state.entries.insert(initial);
let tracker = self.clone();
TrackedWorker { tracker, lid }
}
pub fn list_workers(&self) -> Vec<WorkerReport> {
let mut list = self.lock().entries.iter()
.map(|(_, r)| r.clone())
.collect_vec();
list.sort();
list
}
fn lock(&self) -> MutexGuard<State> {
self.state.lock().unwrap_or_else(|e| e.into_inner())
}
}
impl TrackedWorker {
pub fn update(&mut self, f: impl FnOnce(&mut WorkerReport)) {
let mut state = self.tracker.lock();
if let Some(ent) = state.entries.get_mut(self.lid) {
f(ent)
}
}
}
impl Drop for TrackedWorker {
fn drop(&mut self) {
let mut state = self.tracker.lock();
state.entries.try_remove(self.lid);
}
}
define_derive_deftly! {
export UpdateWorkerReport:
impl $ttype {
pub fn update_worker_report(&self, wr: &mut WorkerReport) {
$(
${when fmeta(worker_report)}
wr.$fname = Some(self.$fname.clone()).into();
)
}
}
}
pub use derive_deftly_template_UpdateWorkerReport;