hive-jobq

A job-DAG scheduler, extracted from hive-c0re's in-tree job_queue as a domain-agnostic library. It schedules a single in-memory graph of nodes over named resources; it knows nothing about containers, rebuilds, or any hyperhive type — the node payload N and resource name R are both generic, so the caller supplies its own domain.

When to use it

Reach for this crate whenever you need to run a DAG of interdependent work items under bounded, named concurrency — the hive-c0re rebuild/lifecycle queue is the first consumer, but nothing here is specific to it. The caller defines the node kinds, wires deps, and supplies a runner; the scheduler decides what can start.

Model

Runtime-only: nothing writes this graph to disk. The serde impls exist for the wire projection (hive-jobq-wire) and a possible future store; no caller loads one, so ids and timestamps are stable within a run, not across restarts. hive-c0re constructs an empty graph every boot and re-derives desired state with its reconcile sweep.

One shared graph for the whole system, not a DAG per job. Enqueuing inserts a self-contained sub-DAG and returns the ids of the nodes the job asked for, in the order it named them; the scheduler runs a continuous loop, starting every node whose deps are satisfied:

A node carries two independent axes: its Deps (ordering + resource needs) and its parent (structural grouping). The parent chain, not the node edges, is what the scheduler consults for resource re-entrancy: a resource unit is held for the acquiring node plus its whole parent subtree, and a descendant needing a resource an ancestor already holds re-uses that grant (a re-entrant borrow, one branch at a time) rather than taking a fresh unit.

A NodeId is opaque, stable and monotonic within a run — a fresh process mints ids from zero, so an id stored outside it is a historical record, not a handle that will resolve later. The scheduler is single-threaded — it owns the resource table and mutates it directly.

Shape

See the crate-root and scheduler module //! docs for the full borrow/release model.