feat(hive-c0re): replace rebuild queue with generic job-DAG queue
jobs are now DAGs of primitive nodes (prebuild, stop-for-update, swap, reconcile, signal, drain, ...) driven by one scheduler with N build slots + per-agent lifecycle leases. per-agent power intent (wanted up/offline) is durable in agent_power.sqlite; Reconcile nodes converge observed state to it. kills the graceful-stop watcher thread, the deferred-start follow-up, and the cascade pre-enqueue (fan-out on MetaLock completion instead). tracker: #2166
This commit is contained in:
parent
79a3993def
commit
7946e03fde
25 changed files with 3673 additions and 2731 deletions
|
|
@ -1,10 +1,12 @@
|
|||
//! Container lifecycle endpoints for the dashboard.
|
||||
//!
|
||||
//! Rebuild / restart / start / stop (hard + graceful) / update-all all
|
||||
//! enqueue onto the rebuild queue, so each shows a visible queued→running
|
||||
//! transient on the dashboard — a direct sub-second start/stop only flashed
|
||||
//! the badge; destroy delegates to `actions::destroy` (optionally
|
||||
//! purging).
|
||||
//! submit DAGs to the job queue (`job_queue::submit`), so each shows a
|
||||
//! visible queued→running transient on the dashboard — a direct
|
||||
//! sub-second start/stop only flashed the badge. Start/stop also
|
||||
//! persist the agent's `wanted` power intent before submitting; the
|
||||
//! DAG's `Reconcile` converges to it. Destroy delegates to
|
||||
//! `actions::destroy` (optionally purging).
|
||||
|
||||
use axum::{
|
||||
extract::{Form, Path as AxumPath, Query, State},
|
||||
|
|
@ -23,6 +25,7 @@ pub(super) struct KillParams {
|
|||
}
|
||||
|
||||
use super::{AppState, error_response, guard_agent_name, strip_container_prefix};
|
||||
use crate::job_queue::{Source, submit};
|
||||
use crate::{actions, lifecycle};
|
||||
|
||||
pub(super) async fn post_rebuild(
|
||||
|
|
@ -33,14 +36,12 @@ pub(super) async fn post_rebuild(
|
|||
if let Some(reject) = guard_agent_name(&state, &logical).await {
|
||||
return reject;
|
||||
}
|
||||
state.coord.rebuild_queue.enqueue(
|
||||
crate::rebuild_queue::QueueKind::Rebuild,
|
||||
logical,
|
||||
crate::rebuild_queue::QueueSource::Manual,
|
||||
submit::rebuild(
|
||||
&state.coord,
|
||||
&logical,
|
||||
Source::Manual,
|
||||
"manual via dashboard ↻ R3BU1LD button".to_owned(),
|
||||
None,
|
||||
);
|
||||
state.coord.emit_rebuild_queue_snapshot();
|
||||
(StatusCode::OK, "ok").into_response()
|
||||
}
|
||||
|
||||
|
|
@ -54,19 +55,17 @@ pub(super) async fn post_kill(
|
|||
return reject;
|
||||
}
|
||||
if params.graceful {
|
||||
// Graceful stop: enqueue the quiesce orchestration (signal the harness
|
||||
// → one stop-checkpoint turn → drain → container stop, with a timeout
|
||||
// fallback to a hard stop). Serialised through the rebuild queue so it
|
||||
// can't race an in-flight rebuild for the same agent, and its per-step
|
||||
// progress surfaces on the queue snapshot + build log.
|
||||
state.coord.rebuild_queue.enqueue(
|
||||
crate::rebuild_queue::QueueKind::GracefulStop,
|
||||
logical,
|
||||
crate::rebuild_queue::QueueSource::Manual,
|
||||
// Graceful stop: submit the quiesce DAG (signal the harness →
|
||||
// one stop-checkpoint turn → drain → container stop, with a
|
||||
// timeout fallback to a hard stop). The agent's lifecycle
|
||||
// lease keeps it from racing an in-flight rebuild for the same
|
||||
// agent, and per-node progress surfaces on the queue snapshot.
|
||||
submit::graceful_stop(
|
||||
&state.coord,
|
||||
&logical,
|
||||
Source::Manual,
|
||||
"manual via dashboard graceful stop".to_owned(),
|
||||
None,
|
||||
);
|
||||
state.coord.emit_rebuild_queue_snapshot();
|
||||
return (StatusCode::OK, "ok").into_response();
|
||||
}
|
||||
// Manager is stoppable from the dashboard like any other
|
||||
|
|
@ -79,14 +78,12 @@ pub(super) async fn post_kill(
|
|||
// `socket_server.rs::ManagerRequest::Kill` stays in place: a
|
||||
// manager calling Kill on its own container is self-suicide
|
||||
// mid-call, not a legitimate operator action.
|
||||
state.coord.rebuild_queue.enqueue(
|
||||
crate::rebuild_queue::QueueKind::Stop,
|
||||
logical,
|
||||
crate::rebuild_queue::QueueSource::Manual,
|
||||
submit::stop(
|
||||
&state.coord,
|
||||
&logical,
|
||||
Source::Manual,
|
||||
"manual via dashboard stop".to_owned(),
|
||||
None,
|
||||
);
|
||||
state.coord.emit_rebuild_queue_snapshot();
|
||||
(StatusCode::OK, "ok").into_response()
|
||||
}
|
||||
|
||||
|
|
@ -98,14 +95,12 @@ pub(super) async fn post_restart(
|
|||
if let Some(reject) = guard_agent_name(&state, &logical).await {
|
||||
return reject;
|
||||
}
|
||||
state.coord.rebuild_queue.enqueue(
|
||||
crate::rebuild_queue::QueueKind::Restart,
|
||||
logical,
|
||||
crate::rebuild_queue::QueueSource::Manual,
|
||||
submit::restart(
|
||||
&state.coord,
|
||||
&logical,
|
||||
Source::Manual,
|
||||
"manual via dashboard ↺ R3START button".to_owned(),
|
||||
None,
|
||||
);
|
||||
state.coord.emit_rebuild_queue_snapshot();
|
||||
(StatusCode::OK, "ok").into_response()
|
||||
}
|
||||
|
||||
|
|
@ -117,14 +112,12 @@ pub(super) async fn post_start(
|
|||
if let Some(reject) = guard_agent_name(&state, &logical).await {
|
||||
return reject;
|
||||
}
|
||||
state.coord.rebuild_queue.enqueue(
|
||||
crate::rebuild_queue::QueueKind::Start,
|
||||
logical,
|
||||
crate::rebuild_queue::QueueSource::Manual,
|
||||
submit::start(
|
||||
&state.coord,
|
||||
&logical,
|
||||
Source::Manual,
|
||||
"manual via dashboard start".to_owned(),
|
||||
None,
|
||||
);
|
||||
state.coord.emit_rebuild_queue_snapshot();
|
||||
(StatusCode::OK, "ok").into_response()
|
||||
}
|
||||
|
||||
|
|
@ -137,15 +130,13 @@ pub(super) async fn post_update_all(State(state): State<AppState>) -> Response {
|
|||
else {
|
||||
continue;
|
||||
};
|
||||
state.coord.rebuild_queue.enqueue(
|
||||
crate::rebuild_queue::QueueKind::Rebuild,
|
||||
logical,
|
||||
crate::rebuild_queue::QueueSource::Manual,
|
||||
submit::rebuild(
|
||||
&state.coord,
|
||||
&logical,
|
||||
Source::Manual,
|
||||
"manual via dashboard 🌀 UPDATE ALL".to_owned(),
|
||||
None,
|
||||
);
|
||||
}
|
||||
state.coord.emit_rebuild_queue_snapshot();
|
||||
(StatusCode::OK, "ok").into_response()
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue