diff --git a/hive-c0re/src/job_queue/mod.rs b/hive-c0re/src/job_queue/mod.rs index 32beb2c5..6b2411df 100644 --- a/hive-c0re/src/job_queue/mod.rs +++ b/hive-c0re/src/job_queue/mod.rs @@ -217,15 +217,7 @@ impl JobQueue { ) -> anyhow::Result { let mut inner = self.lock(); let container = inner - .append( - NodeKind::Dag { - source, - reason, - created_at: Utc::now(), - }, - Vec::new(), - None, - ) + .append(NodeKind::Dag { source, reason }, Vec::new(), None) .map_err(|e| anyhow::anyhow!("job_queue: container insert failed: {e}"))?; insert_group(&mut inner, declare, Some(container))?; drop(inner); @@ -407,15 +399,15 @@ fn container(sched: &Sched, dag_id: u64) -> Option { /// DAG drops out of the snapshot entirely (a `Failed` one lingers until /// aged out). fn dag_view(sched: &Sched, container: NodeId) -> Option { - // Read straight off the container's payload: the three fields have a + // Read straight off the container's payload: the domain fields have a // single home there, so an intermediate owned copy of them was a second // type describing the same data rather than a grouping side-table. - let NodeKind::Dag { - source, - reason, - created_at, - } = &sched.graph().node(container)?.payload - else { + // + // `created_at` is NOT among them — it comes off the container node itself + // below, where the graph stamps it for every node. Keeping a payload copy + // would record one instant in two places. + let node = sched.graph().node(container)?; + let NodeKind::Dag { source, reason } = &node.payload else { return None; }; let all: Vec<_> = sched.graph().descendants(container).collect(); @@ -494,7 +486,7 @@ fn dag_view(sched: &Sched, container: NodeId) -> Option { id: container.get(), source: *source, reason: reason.clone(), - created_at: *created_at, + created_at: node.created_at, started_at: started.into_iter().min(), finished_at: is_terminal.then(|| finished.into_iter().max()).flatten(), nodes, diff --git a/hive-c0re/src/job_queue/model.rs b/hive-c0re/src/job_queue/model.rs index e783c05c..3b8aaf4b 100644 --- a/hive-c0re/src/job_queue/model.rs +++ b/hive-c0re/src/job_queue/model.rs @@ -12,7 +12,6 @@ //! DAG can span agents). See `docs/coordinator.md::Job queue` for the //! full design. -use chrono::{DateTime, Utc}; pub use hive_host_sock::jobs::{DagView, PermPayload, Source, State}; use serde::Serialize; @@ -276,11 +275,12 @@ pub enum NodeKind { /// the DAG state. Pure grouping — lease- and /// build-slot-exempt; the executor instant-completes it (`Done`) so it /// reaches `Finishing` and its children start. - Dag { - source: Source, - reason: String, - created_at: DateTime, - }, + /// + /// No `created_at` here: the graph stamps [`hive_jobq::Node::created_at`] on + /// every node at insert, so the container already has one. A second copy in + /// the payload would be the same instant recorded twice, with only this + /// variant's version reachable to a generic viewer. + Dag { source: Source, reason: String }, } /// How a hive-c0re node describes itself to a generic graph viewer.