job_queue: finish reparent call-site swap, delete dead sync path
This commit is contained in:
parent
05b373474a
commit
18745f1a98
8 changed files with 94 additions and 216 deletions
|
|
@ -926,9 +926,11 @@ impl Coordinator {
|
|||
}
|
||||
}
|
||||
|
||||
/// Apply a topology reparent + fan the resulting notifications
|
||||
/// out to the three affected agents. On success, drops a
|
||||
/// one-line system message into the inbox of:
|
||||
/// Apply topology reparent(s) + fan the resulting notifications out to
|
||||
/// the affected agents. Applies all moves under a single `META_LOCK`
|
||||
/// acquisition (one git commit — a single-move call is just a
|
||||
/// one-element slice) then, for each move that actually changed
|
||||
/// topology, drops a one-line system message into the inbox of:
|
||||
///
|
||||
/// 1. The **old parent** (if any) — `"{child} moved out of your
|
||||
/// subtree to {new_parent_or_root}"`.
|
||||
|
|
@ -946,76 +948,6 @@ impl Coordinator {
|
|||
/// `from = hive_sh4re::SYSTEM_SENDER` so the dashboard renders
|
||||
/// them under the existing system-source styling.
|
||||
///
|
||||
/// Idempotent: if `topology::set_parent` skipped the disk write
|
||||
/// (same-parent no-op), no messages fire. The `topology` module's
|
||||
/// validation (`apply_set_parent`: unknown agent, cycle, etc.)
|
||||
/// runs *before* any message is sent, so a refused move never
|
||||
/// notifies anyone.
|
||||
///
|
||||
/// Also drives a `rescan_containers_and_emit` after the write so
|
||||
/// the dashboard tree re-renders without polling.
|
||||
pub async fn reparent_with_notify(
|
||||
self: &Arc<Self>,
|
||||
child: &str,
|
||||
new_parent: Option<&str>,
|
||||
) -> std::result::Result<(), String> {
|
||||
// Snapshot the old parent BEFORE the write so the
|
||||
// notifications can describe both sides of the change.
|
||||
let topo_before = crate::topology::read();
|
||||
let old_parent = topo_before.get(child).cloned().flatten();
|
||||
|
||||
// The disk write + git commit happen here under META_LOCK, so
|
||||
// the topology.json change is committed atomically and the
|
||||
// working tree is never left dirty between the write and the
|
||||
// next meta operation. Topology validation + idempotent
|
||||
// fast-path inside `set_parent` may short-circuit (same
|
||||
// parent → no-op). We mirror the same idempotent shape for
|
||||
// the notifications: if nothing changed, send nothing.
|
||||
crate::meta::commit_topology(child, new_parent).await?;
|
||||
|
||||
let changed = old_parent.as_deref() != new_parent;
|
||||
if changed {
|
||||
let old_label = old_parent.as_deref().unwrap_or("<root>");
|
||||
let new_label = new_parent.unwrap_or("<root>");
|
||||
// System-source notifications. Best-effort: a failed broker
|
||||
// send is logged + ignored so a transient sqlite error
|
||||
// doesn't bubble out and unwind the topology write.
|
||||
if let Some(op) = old_parent.as_deref() {
|
||||
let _ = self.broker.send(&hive_sh4re::Message {
|
||||
from: hive_sh4re::trusted_sender(hive_sh4re::SYSTEM_SENDER),
|
||||
to: op.to_owned(),
|
||||
body: format!("{child} moved out of your subtree to {new_label}"),
|
||||
in_reply_to: None,
|
||||
});
|
||||
}
|
||||
if let Some(np) = new_parent {
|
||||
let _ = self.broker.send(&hive_sh4re::Message {
|
||||
from: hive_sh4re::trusted_sender(hive_sh4re::SYSTEM_SENDER),
|
||||
to: np.to_owned(),
|
||||
body: format!(
|
||||
"{child} just moved into your subtree (was previously under {old_label})"
|
||||
),
|
||||
in_reply_to: None,
|
||||
});
|
||||
}
|
||||
// Coalesce: if a prior move notification is already pending in
|
||||
// the broker (agent was offline for multiple moves), update it
|
||||
// in-place so the agent sees "A to C" not "A to B" then "B to C".
|
||||
let _ = self
|
||||
.broker
|
||||
.send_coalescing_reparent(child, old_label, new_label);
|
||||
}
|
||||
|
||||
// Rescan + diff-emit regardless of whether messages fired —
|
||||
// even an idempotent no-op might have happened concurrently
|
||||
// with another lifecycle event the dashboard cares about.
|
||||
self.rescan_containers_and_emit().await;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Batch version of [`reparent_with_notify`]: applies all moves under a
|
||||
/// single `META_LOCK` acquisition (one git commit) then sends per-agent
|
||||
/// notifications for each move that actually changed topology.
|
||||
/// First validation failure aborts the whole batch with no disk writes.
|
||||
///
|
||||
/// # Errors
|
||||
|
|
|
|||
Loading…
Reference in a new issue