use std::sync::Arc;
use std::time::Duration;
use crate::controller::slot::SlotPhase;
use crate::controller::view::{ControllerSnapshot, SlotStatusKind, SlotView};
use super::Controller;
impl Controller {
pub(crate) async fn snapshot(&self) -> ControllerSnapshot {
let keys: Vec<Arc<str>> = self.slots.iter().map(|e| Arc::clone(e.key())).collect();
let mut slots = Vec::with_capacity(keys.len());
for key in keys {
let Some(slot_arc) = self.slots.get(&*key).map(|e| e.clone()) else {
continue;
};
let slot = slot_arc.lock().await;
let phase = slot.phase();
let (status, status_for) = match phase {
SlotPhase::Idle => (SlotStatusKind::Idle, Duration::ZERO),
SlotPhase::Admitting { since, .. } => (SlotStatusKind::Admitting, since.elapsed()),
SlotPhase::Running { started_at, .. } => {
(SlotStatusKind::Running, started_at.elapsed())
}
SlotPhase::CancelPendingAdmission { requested_at, .. }
| SlotPhase::Terminating { requested_at, .. } => {
(SlotStatusKind::Terminating, requested_at.elapsed())
}
};
slots.push(SlotView {
slot: Arc::clone(&key),
status,
owner_id: phase.owner_id(),
queue_depth: slot.queue.len(),
status_for,
});
}
slots.sort_by(|a, b| a.slot.cmp(&b.slot));
ControllerSnapshot { slots }
}
}