Skip to main content

stackless_core/engine/
progress.rs

1//! Step progress events during `up` — substrate-agnostic telemetry for
2//! agents and human operators.
3
4use super::plan::StepKind;
5
6#[derive(Debug, Clone, Copy, PartialEq, Eq)]
7pub enum StepProgressEvent {
8    Started,
9    Skipped,
10    Completed,
11    Failed,
12}
13
14#[derive(Debug, Clone)]
15pub struct StepProgress {
16    pub event: StepProgressEvent,
17    pub instance: String,
18    pub step_id: String,
19    pub step_kind: StepKind,
20    pub node: String,
21    /// 1-based index within the plan.
22    pub index: usize,
23    pub total: usize,
24    /// Set on [`StepProgressEvent::Failed`] when a stable code is known.
25    pub code: Option<&'static str>,
26    /// Wall-clock time of this event (Unix epoch milliseconds).
27    pub at_epoch_ms: i64,
28    /// Elapsed time since `step_started`, set on completed/failed/skipped.
29    pub duration_ms: Option<u64>,
30}
31
32pub trait ProgressSink {
33    fn on_step(&mut self, progress: StepProgress);
34}
35
36#[derive(Debug, Default)]
37pub struct NullProgress;
38
39impl ProgressSink for NullProgress {
40    fn on_step(&mut self, _progress: StepProgress) {}
41}
42
43pub fn epoch_ms() -> i64 {
44    std::time::SystemTime::now()
45        .duration_since(std::time::UNIX_EPOCH)
46        .map(|d| d.as_millis() as i64)
47        .unwrap_or(0)
48}