fix(#1218): bulk topology move uses one git commit via new set-parent-bulk endpoint
This commit is contained in:
parent
644519f358
commit
7ec0a36d7a
4 changed files with 179 additions and 4 deletions
|
|
@ -716,6 +716,57 @@ impl Coordinator {
|
|||
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.
|
||||
pub async fn reparent_bulk_with_notify(
|
||||
self: &Arc<Self>,
|
||||
moves: &[(&str, Option<&str>)],
|
||||
) -> std::result::Result<(), String> {
|
||||
if moves.is_empty() {
|
||||
return Ok(());
|
||||
}
|
||||
// bulk_commit_topology applies all set_parent calls under one lock
|
||||
// and returns (child, old_parent) for every move that changed.
|
||||
let changed = crate::meta::bulk_commit_topology(moves).await?;
|
||||
|
||||
// Send per-agent notifications for each changed move.
|
||||
for (child, old_parent) in &changed {
|
||||
// Find the new parent from the moves slice.
|
||||
let new_parent = moves
|
||||
.iter()
|
||||
.find(|(c, _)| *c == child)
|
||||
.and_then(|(_, np)| *np);
|
||||
let old_label = old_parent.as_deref().unwrap_or("<root>");
|
||||
let new_label = new_parent.unwrap_or("<root>");
|
||||
if let Some(op) = old_parent.as_deref() {
|
||||
let _ = self.broker.send(&hive_sh4re::Message {
|
||||
from: hive_sh4re::SYSTEM_SENDER.to_owned(),
|
||||
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::SYSTEM_SENDER.to_owned(),
|
||||
to: np.to_owned(),
|
||||
body: format!(
|
||||
"{child} just moved into your subtree (was previously under {old_label})"
|
||||
),
|
||||
in_reply_to: None,
|
||||
});
|
||||
}
|
||||
let _ = self
|
||||
.broker
|
||||
.send_coalescing_reparent(child, old_label, new_label);
|
||||
}
|
||||
|
||||
self.rescan_containers_and_emit().await;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Read-only snapshot of the last cached container view. Used by
|
||||
/// `/api/state` to cold-load page-open clients without re-running
|
||||
/// `nixos-container list` themselves; the
|
||||
|
|
|
|||
Loading…
Reference in a new issue