//! The concrete resource type the rebuild queue schedules over — the bridge //! from hive-c0re's [`super::model::NodeKind`] onto the domain-agnostic `hive-jobq` crate. //! `hive-jobq` is generic over a resource type `R: Clone + Eq + Hash` and a node //! payload `N`; here `R` is [`Resource`] and `N` is [`super::model::NodeKind`] directly (each //! variant carries the agent it targets). //! //! **A node's resources are declared where the node is constructed** with //! `.needs(…)`, not derived from its kind. Deriving them made the requirement a //! property of the *kind*, which let a kind that happened to run under a //! holding ancestor declare nothing at all. //! //! All of a node's resource edges are acquired **atomically** //! (`try_acquire_all`) — a node never holds one resource while waiting on //! another, so the multi-resource nodes (a `MetaLock` wants a build slot *and* //! the meta window) cannot deadlock against each other. /// The two resource classes the queue gates concurrency on, as the crate's /// generic resource type `R`. What each holds, who declares it, and the /// exemptions: see `docs/scheduler/coordinator.md`'s _Scheduler semantics_ /// (build slots, the per-agent lease) and _Two further layers protect the /// meta repo_ (the deploy window) sections — this enum stays the one-line /// summary, not a second copy. #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub enum Resource { /// One of the `buildSlots` permits, held by a nix-heavy node for its /// duration. BuildSlot, /// The per-agent lifecycle lease — globally exclusive per agent across /// all DAGs. Agent(String), /// The meta-repo mutation window — a global singleton held by any node /// that mutates the meta repo, so two meta mutations never interleave. MetaWindow, } /// This resource's name on the generic graph wire. /// /// `hive_jobq` is generic over the resource type, so a viewer that can render /// any graph gets a string here rather than this enum. The `agent:` prefix /// keeps the per-agent leases from colliding with a hypothetical global /// resource that happens to share an agent's name. impl hive_jobq_wire::WireResource for Resource { fn name(&self) -> String { match self { Resource::BuildSlot => "build-slot".to_owned(), Resource::Agent(agent) => format!("agent:{agent}"), Resource::MetaWindow => "meta-window".to_owned(), } } }